Next.js中useFormState结合Server Actions的TypeScript类型报错解决
修复Next.js Server Actions与useFormState的TypeScript类型不兼容问题
核心问题分析
报错根源在于3个类型不匹配点:
- Form组件中
action的类型定义错误,将Server Action标记为返回void,但实际Server Action是异步函数,返回Promise - 未显式指定
useFormState的泛型参数,导致TypeScript自动推断的状态类型与自定义State不统一 - Server Action的返回值结构未严格对齐
State类型定义
步骤1:修正State类型定义
确保@/types/formState.ts包含所有可能的返回字段,统一状态结构:
// @/types/formState.ts export type State = { message: string | null; errors: Record<string, string[] | undefined>; success?: boolean; };
步骤2:修复Form组件的类型错误
调整action参数类型,并显式指定useFormState的泛型:
import { useFormState } from "react-dom"; import { State } from "@/types/formState"; // 修正action类型:异步函数,接收State和FormData,返回Promise<State> type Props = { children: React.ReactNode; action: (prevState: State, formData: FormData) => Promise<State>; }; const Form = ({ children, action }: Props) => { // 显式指定initialState的类型为State const initialState: State = { message: null, errors: {} }; // 显式传入泛型参数State,让TypeScript明确状态类型 const [state, dispatch] = useFormState<State>(action, initialState); return ( <form action={dispatch} className="w-full flex justify-center" autoComplete="off" > <div className={`w-full`}> {children} </div> </form> ); }; export default Form;
步骤3:统一Server Action的返回结构
确保createUserAccount的返回值严格符合State类型:
"use server"; import { State } from "@/types/formState"; import userAccountSchema from "@/validation/schemas/createUserAccount"; // 显式标记返回类型为Promise<State> export async function createUserAccount(prevState: State, formData: FormData): Promise<State> { const parsedData = userAccountSchema.safeParse({ firstname: formData.get("firstname"), lastname: formData.get("lastname"), }); if (!parsedData.success) { return { ...prevState, // 保留之前的状态(可选,根据业务需求调整) message: null, errors: parsedData.error.flatten().fieldErrors, success: false, }; } // 成功时返回完整的State结构 return { message: "账户创建成功!", errors: {}, success: true, }; }
为什么这样修复?
- 移除了
action类型中的void,匹配Server Action异步函数的返回特性 - 显式泛型参数让
useFormState明确状态类型,避免自动推断偏差 - 统一Server Action的返回结构,确保所有分支都输出符合
State定义的对象
内容的提问来源于stack exchange,提问作者Alexandre Paiva
相关产品推荐
相关产品推荐

