TypeScript中Formik的onSubmit类型报错如何解决
报错信息
Type '(values: { email: string; password: string; }) => { type: string; payload: { email: string | null; password: string | null; }; }' is not assignable to type '((values: { email: string; password: string; }, formikHelpers: FormikHelpers<{ email: string; password: string; }>) => void | Promise) & ((values: { email: string; password: string; }) => { ...; })'.
Type '(values: { email: string; password: string; }) => { type: string; payload: { email: string | null; password: string | null; }; }' is not assignable to type '(values: { email: string; password: string; }, formikHelpers: FormikHelpers<{ email: string; password: string; }>) => void | Promise'.
Type '{ type: string; payload: { email: string | null; password: string | null; }; }' is not assignable to type 'void | Promise'.
问题相关代码
Formik 组件配置
<Formik initialValues={{ email: '', password: ''}} validationSchema = { LoginSchema } validateOnChange={false} onSubmit={ (values) => requestLogin(values.email, values.password)} >
requestLogin Action 定义
export const requestLogin = (email: string, password: string) => ({ type: types.AUTH_USER, payload: { email: email || null, password: password || null } });
报错根因
- 你对
requestLogin两个string类型入参的写法完全正确,报错和入参定义无关。 - Formik的
onSubmit属性对传入回调有明确类型约束:回调的返回值必须是void(无返回值)或者Promise类型。 - 你当前使用了箭头函数简写语法,省略了函数体大括号,会直接把
requestLogin()的执行结果作为onSubmit回调的返回值。而requestLogin返回的是一个普通的Redux Action对象(包含type、payload字段的普通对象),既不是无返回值,也不是Promise类型,完全不符合onSubmit的类型要求,因此触发报错。
修复方案
把onSubmit的箭头函数改成带大括号的完整函数体,在函数内部调用requestLogin即可,不要主动return它的返回值,让回调默认返回undefined(符合void类型要求):
<Formik initialValues={{ email: '', password: ''}} validationSchema = { LoginSchema } validateOnChange={false} onSubmit={ (values) => { requestLogin(values.email, values.password) }} >
如果你是搭配react-redux的dispatch触发action,写法逻辑一致,只要不把Action对象作为onSubmit回调的返回值即可:
const dispatch = useDispatch() // 组件内其他逻辑 <Formik initialValues={{ email: '', password: ''}} validationSchema = { LoginSchema } validateOnChange={false} onSubmit={ (values) => { dispatch(requestLogin(values.email, values.password)) }} >
内容的提问来源于stack exchange,提问作者Victor Nițică

