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

TypeScript:泛型函数适配多表单类型的类型问题解决方案

解决泛型表单验证函数的类型报错问题

问题原因

当前泛型T没有任何约束,TypeScript无法推断出T中除formError外的字段都属于InputState类型,所以访问formData[index].validation时会触发“Property 'validation' does not exist”的类型错误。

解决方案

方案1:定义通用表单约束类型

先创建一个通用的表单类型,统一规范所有表单的结构,让TypeScript明确字段类型:

// 定义通用表单类型:继承FormError,其余字段均为InputState<T>
type GenericForm<FieldTypes extends Record<string, any>> = FormError & {
  [FieldName in keyof FieldTypes]: InputState<FieldTypes[FieldName]>;
};

// 用通用类型重构现有表单(也可以直接用它创建新表单)
type WorkoutForm = GenericForm<{
  trainingType: trainingType;
  name: string;
  date: string;
}>;

type LoginForm = GenericForm<{
  email: string;
  password: string;
}>;

// 修改验证函数,添加泛型约束
public validate<T extends GenericForm<any>>(formData: T, index: Exclude<keyof T, 'formError'>): T {
  // 现在可以正常访问validation属性
  const validation = formData[index].validation;
  
  // 示例验证逻辑:遍历规则检查输入
  const input = formData[index];
  if (input.validation) {
    input.onError = false;
    input.errorMessage = undefined;
    for (const rule of input.validation) {
      const { isValid, message } = rule.validate(input.value);
      if (!isValid) {
        input.onError = true;
        input.errorMessage = message;
        break; // 遇到第一个错误就停止
      }
    }
  }

  // 更新整体表单错误信息
  const hasFieldErrors = Object.values(formData)
    .some(item => 'onError' in item && item.onError);
  formData.formError = hasFieldErrors ? '存在输入错误,请检查' : '';

  return formData;
}

方案2:直接给泛型添加约束(无需重构现有表单)

如果不想修改现有表单的定义,可以直接在泛型上添加约束,确保除formError外的字段都是InputState类型:

public validate<T extends FormError & { 
  [K in Exclude<keyof T, 'formError'>]: InputState<any> 
}>(formData: T, index: Exclude<keyof T, 'formError'>): T {
  const validation = formData[index].validation;
  // 你的验证逻辑
  return formData;
}

使用优化

调用验证函数时,TypeScript可以自动推断泛型类型,无需显式传入:

function handleFormData(index: Exclude<keyof LoginForm, 'formError'>, value: string): void {
  const currentFormData = formData;
  currentFormData[index].value = value;
  // 自动推断T为LoginForm,无需写<LoginForm>
  const validatedData = FormValidation.getInstance().validate(currentFormData, index);
}

关键思路

核心是通过泛型约束告诉TypeScript:传入的表单类型T必须满足「继承FormError,且所有非formError的字段都是InputState类型」,这样TypeScript就能确定formData[index]拥有validation属性,从而消除类型报错。

内容的提问来源于stack exchange,提问作者Hadock

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:20:41