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

TypeScript中如何从数组属性值推断接口属性名?

如何从FormField数组推断出对应属性名的FormModel接口

当然可以实现这个需求!你的思路方向是对的,但TypeScript里索引签名的写法需要调整一下,我们得结合索引类型查询和映射类型来正确提取数组元素的name属性值作为新接口的键。

问题出在哪?

你原来的写法{ [K['name'] in T]: string }有两个核心问题:

  • T是数组类型,不能直接用in遍历,得先获取数组元素的具体类型;
  • K['name']的写法不符合TypeScript映射类型的语法,正确姿势是先拿到键的联合类型,再用K in 联合类型来遍历生成属性。

正确实现步骤

  1. 让TypeScript捕获精确的name字面量类型
    首先要给fields变量加上as const断言,这样TypeScript会把每个元素的name推断为具体的字符串字面量(比如'givenName'、'familyName'),而不是宽泛的string类型——这是精确推断的关键:

    interface FormField { name: string; }
    const fields = [ { name: 'givenName' }, { name: 'familyName' } ] as const;
    
  2. 定义正确的Model类型
    利用T[number]获取数组元素的类型,再通过['name']提取其name属性的联合类型,最后用映射类型生成目标接口:

    type Model<T extends readonly FormField[]> = {
      [K in T[number]['name']]: string;
    };
    
  3. 生成目标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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:54:04