如何为接收Field类型rest参数的form函数指定正确返回类型?
解决方案
要让form函数返回精确的键值类型映射,需要调整泛型约束和返回类型的定义,利用TypeScript的条件类型和映射类型来关联每个字段的name和对应的value类型。
修改后的代码
interface Field<T> { name: string; value: T; } function form<T extends readonly Field<any>[]>( ...fields: T ): { [K in T[number]['name']]: Extract<T[number], { name: K }>['value'] } { // 断言data为目标类型,避免类型报错 const data = {} as { [K in T[number]['name']]: Extract<T[number], { name: K }>['value'] }; fields.forEach((field) => { data[field.name as keyof typeof data] = field.value; }); return data; } const age: Field<number> = { name: 'age', value: 30 }; const sex: Field<string> = { name: 'sex', value: 'men' }; const data = form(age, sex); // 此时data类型为 { age: number, sex: string }
关键修改说明
- 泛型约束:将
T extends Field<unknown>[]改为T extends readonly Field<any>[],确保TypeScript能正确推断元组中每个元素的具体类型(而非宽松的数组类型)。 - 返回类型:
[K in T[number]['name']]:遍历所有字段的name作为结果对象的键。Extract<T[number], { name: K }>['value']:通过Extract条件类型,筛选出当前键K对应的Field类型,再提取其value的精确类型,避免了所有value类型的联合。
- 类型断言:在初始化
data时,直接断言为目标返回类型,解决赋值过程中的类型不兼容问题。
可行性验证
该方案在TypeScript 4.9.3版本完全可行,利用了TypeScript 2.8+支持的条件类型(Extract)和映射类型特性,能够精准推断每个字段对应的类型,满足需求。
内容的提问来源于stack exchange,提问作者kopilot.schneider
相关产品推荐
相关产品推荐

