TypeScript中如何从数组属性值推断接口属性名?
如何从FormField数组推断出对应属性名的FormModel接口
当然可以实现这个需求!你的思路方向是对的,但TypeScript里索引签名的写法需要调整一下,我们得结合索引类型查询和映射类型来正确提取数组元素的name属性值作为新接口的键。
问题出在哪?
你原来的写法{ [K['name'] in T]: string }有两个核心问题:
T是数组类型,不能直接用in遍历,得先获取数组元素的具体类型;K['name']的写法不符合TypeScript映射类型的语法,正确姿势是先拿到键的联合类型,再用K in 联合类型来遍历生成属性。
正确实现步骤
让TypeScript捕获精确的name字面量类型
首先要给fields变量加上as const断言,这样TypeScript会把每个元素的name推断为具体的字符串字面量(比如'givenName'、'familyName'),而不是宽泛的string类型——这是精确推断的关键:interface FormField { name: string; } const fields = [ { name: 'givenName' }, { name: 'familyName' } ] as const;定义正确的Model类型
利用T[number]获取数组元素的类型,再通过['name']提取其name属性的联合类型,最后用映射类型生成目标接口:type Model<T extends readonly FormField[]> = { [K in T[number]['name']]: string; };生成目标FormModel
用typeof fields获取数组的类型,传入Model类型即可得到你想要的接口:type FormModel = Model<typeof fields>; // 此时FormModel的类型完全符合预期: // interface FormModel { // givenName: string; // familyName: string; // }
关键知识点解析
as const:将数组和对象转为只读的字面量类型,确保TypeScript保留精确的字符串值信息,而不是模糊的string;T[number]:对于数组类型T,T[number]代表数组中单个元素的类型;T[number]['name']:索引类型查询,提取元素类型中name属性的所有可能值,形成一个联合类型;- 映射类型:通过
[K in 联合类型]遍历联合类型中的每个值,将其作为新对象类型的键。
内容的提问来源于stack exchange,提问作者dndr
相关产品推荐
相关产品推荐

