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

实现接收字段数组与FormData的类型安全TS表单提取函数

实现数组参数的类型安全表单值提取函数

需求说明

需要编写一个TypeScript函数,接收两个参数:

  • 字段配置数组:每个元素包含name属性和可选type属性(type仅支持'number'或默认)
  • FormData对象

函数返回一个类型安全的对象:

  • 键为字段的name值
  • 值的类型匹配字段type:未指定则为string,指定'number'则转为number类型

预期效果:

const formData = new FormData();
formData.append('name', 'John Doe');
formData.append('age', '25');

const fields = [{ name: 'name' }, { name: 'age', type: 'number' }] as const;
const data = extractFormValues(fields, formData);
// 类型自动推断为 { name: string; age: number }
// 运行值为 { name: 'John Doe', age: 25 }

解决方案

1. 定义基础类型

首先明确字段的类型约束,限制type只能是'number'或undefined:

type Field = {
  name: string;
  type?: 'number';
};

2. 实现类型安全的函数

通过泛型和映射类型,从数组元素中提取键和对应值的类型:

// 从字段数组类型T中提取最终返回的对象类型
type ExtractFormValues<T extends readonly Field[]> = {
  [K in T[number]['name']]: 
    Extract<T[number], { name: K }>['type'] extends 'number' 
      ? number 
      : string;
};

const extractFormValues = <T extends readonly Field[]>(
  fields: T,
  formData: FormData
): ExtractFormValues<T> => {
  const result = {} as ExtractFormValues<T>;
  
  for (const field of fields) {
    const value = formData.get(field.name);
    // 假设表单字段均有值,处理FormData.get可能返回null的情况
    const rawValue = value as string;
    
    if (field.type === 'number') {
      result[field.name as keyof ExtractFormValues<T>] = Number(rawValue) as ExtractFormValues<T>[keyof ExtractFormValues<T>];
    } else {
      result[field.name as keyof ExtractFormValues<T>] = rawValue as ExtractFormValues<T>[keyof ExtractFormValues<T>];
    }
  }
  
  return result;
};

3. 使用示例

注意需要给字段数组添加as const,让TypeScript推断出字面量类型,否则会丢失具体的name和type信息:

const fields = [{ name: 'name' }, { name: 'age', type: 'number' }] as const;

const formData = new FormData();
formData.append('name', 'John Doe');
formData.append('age', '25');

const data = extractFormValues(fields, formData);
// data的类型为 { name: string; age: number }
console.log(data.name); // 类型提示为string
console.log(data.age); // 类型提示为number

关键说明

  • 泛型约束:T extends readonly Field[]确保传入的数组元素符合Field类型,readonly允许使用as const的只读数组
  • 映射类型ExtractFormValues:遍历数组中所有元素的name作为键,通过Extract找到对应name的字段类型,判断其type来确定值的类型
  • as const的作用:强制TypeScript将数组元素的name和type推断为字面量类型(比如'name'而非string,'number'而非string),这样才能正确生成返回对象的类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:03:27