Formik initialValues赋值触发ts(2322)类型错误求助
解决Formik单组件适配多表单变体的TypeScript类型错误
错误原因
你遇到的ts(2322)错误,本质是表单值类型和initialValues的类型不匹配:当表单变体为pro时,要求值类型包含company字段,但基础版的initialValues缺少该字段,TypeScript无法自动推断两种变体下的类型对应关系。
解决方案
通过泛型关联表单变体与值类型,让TypeScript根据当前变体自动推导正确的initialValues类型,同时保证类型安全。
1. 定义基础与扩展表单类型
先明确两种表单的结构,让专业版继承基础版的字段:
// 基础注册表单字段 interface ISignup { email: string; password: string; } // 专业版额外包含company字段 interface ISignupPro extends ISignup { company: string; }
2. 关联变体与值类型
用泛型条件类型,根据表单变体自动匹配对应的值类型:
// 表单变体枚举 type FormVariant = 'basic' | 'pro'; // 根据变体推导对应的值类型 type FormValues<T extends FormVariant> = T extends 'pro' ? ISignupPro : ISignup;
3. 实现泛型Formik组件
编写泛型组件,让initialValues的类型随变体动态变化:
import { Formik, Form, Field } from 'formik'; function SignupForm<T extends FormVariant>({ variant }: { variant: T }) { // 根据变体生成对应的初始值 const getInitialValues = (): FormValues<T> => { if (variant === 'pro') { return { email: '', password: '', company: '' } as FormValues<T>; } return { email: '', password: '' } as FormValues<T>; }; return ( <Formik<FormValues<T>> initialValues={getInitialValues()} onSubmit={(values) => { // 提交时values的类型会自动匹配当前变体 console.log('提交数据:', values); }} > {() => ( <Form> <Field name="email" type="email" placeholder="邮箱" /> <Field name="password" type="password" placeholder="密码" /> {/* 仅专业版显示company字段 */} {variant === 'pro' && ( <Field name="company" placeholder="公司名称" /> )} <button type="submit">提交</button> </Form> )} </Formik> ); } // 使用示例 <SignupForm variant="basic" /> <SignupForm variant="pro" />
替代方案:类型断言快速修复
如果不想用泛型,也可以通过类型断言临时解决,但要确保业务逻辑中变体与initialValues严格对应:
const SignupForm = ({ variant }: { variant: FormVariant }) => { const initialValues = variant === 'pro' ? { email: '', password: '', company: '' } : { email: '', password: '' }; return ( <Formik<ISignup | ISignupPro> initialValues={initialValues as ISignup | ISignupPro} onSubmit={(values) => { if (variant === 'pro') { // 此处可以安全访问(values as ISignupPro).company console.log('公司:', (values as ISignupPro).company); } }} > {/* 表单内容同前 */} </Formik> ); };
注意:类型断言会跳过TypeScript的部分类型检查,建议优先使用泛型方案保证类型安全。
内容的提问来源于stack exchange,提问作者Cyril Zlachevsky
相关产品推荐
相关产品推荐

