You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:31:03