Next.js 15 + TypeScript:如何为组件的服务端动作(Server Action)属性正确定义类型?
Next.js 15 + TypeScript:如何为组件的服务端动作(Server Action)属性正确定义类型?
嘿,这个问题我之前也踩过坑,用TypeScript泛型就能完美解决——既保留类型安全,又能让你的ProductForm组件适配任意服务端动作函数,不用再写any这种偷懒的类型啦!
核心思路:服务端动作本质是异步函数
服务端动作其实就是普通的异步函数,所以我们可以用泛型来约束它的输入参数和返回值类型,让组件能灵活适配不同的动作。
改造你的ProductForm组件
直接上改好的代码,一步步看:
'use client'; // 定义泛型Props接口,TInput是动作函数的参数类型,TOutput是返回值类型 interface ProductFormProps<TInput, TOutput> { // 明确action是接收TInput参数、返回Promise<TOutput>的异步函数 action: (data: TInput) => Promise<TOutput>; actionType: string; } // 组件对应使用泛型,让TypeScript自动推导类型 const ProductForm = <TInput, TOutput>({ action, actionType }: ProductFormProps<TInput, TOutput>) => { // 举个例子:调用action时,TypeScript会自动提示参数和返回值类型 const handleSubmit = async (formData: TInput) => { const result = await action(formData); // 这里result的类型就是TOutput,比如你的addProduct返回的{ success: boolean } | null if (result?.success) { console.log('操作成功!'); } }; return <> {/* 你的表单渲染逻辑 */} </>; }; export default ProductForm;
在页面中使用时自动推导类型
回到你的ProductsAddPage,根本不需要手动指定泛型,TypeScript会自动识别addProduct的参数(Product类型)和返回值({ success: boolean } | null):
import { addProduct } from '@/actions/products-actions'; import ProductForm from './ProductForm'; const ProductsAddPage = async () => { return <> <h1>Add Post</h1> <section> <ProductForm action={addProduct} actionType='add' /> </section> </>; }; export default ProductsAddPage;
进阶:给返回值加通用约束
如果你的所有服务端动作返回值都有success字段,还可以给泛型加约束,让类型检查更严格:
// 定义通用的服务端动作返回值结构 interface BaseServerActionResult { success: boolean; message?: string; // 可选的提示信息 } // 修改泛型接口,让TOutput必须符合这个结构 interface ProductFormProps<TInput, TOutput extends BaseServerActionResult> { action: (data: TInput) => Promise<TOutput>; actionType: string; }
这样一来,在组件里使用result.success时,TypeScript会确保这个属性一定存在,不会出现类型报错。
备注:内容来源于stack exchange,提问作者Pippy Longstocking
相关产品推荐
相关产品推荐

