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

TypeScript中如何提取数组对象属性值生成对应联合类型?

TypeScript从数组提取属性值字面量联合类型实现方案

要实现从数组中提取指定属性的字面量联合类型,核心需要两步:一是让TypeScript保留数组内属性的字面量类型,避免被拓宽为通用的string类型;二是通过索引访问类型提取对应属性的联合值。

  • 最简实现(推荐)
    给原数组添加as const常量断言,锁定数组内部所有值的字面量类型,再通过索引访问语法提取属性:

    // as const 禁止类型拓宽,保留每个id的字面量值
    const d = [{id: 'Cat'}, {id: 'Dog'}] as const;
    
    type ids = typeof d[number]['id'];
    // 此时ids的类型为 'Cat' | 'Dog',完全符合要求
    

    实现原理说明:

    • typeof d 拿到整个数组的类型
    • [number] 是数组类型的标准索引访问写法,传入number可以拿到数组所有元素组成的联合类型,即{readonly id: "Cat"} | {readonly id: "Dog"}
    • 最后拼接['id'],即可取出联合类型中每个成员的id属性值,组成最终的字面量联合类型
  • 不修改原数组声明的兼容写法(TS 5.0+支持)
    如果数组是外部传入、不方便直接加as const,可以用const类型参数封装工具函数,自动保留字面量类型:

    // 封装通用的字面量数组固定函数
    const makeLiteralArray = <const T extends readonly unknown[]>(arr: T) => arr;
    const d = makeLiteralArray([{id: 'Cat'}, {id: 'Dog'}]);
    
    type ids = typeof d[number]['id']; // 同样得到 'Cat' | 'Dog'
    
  • 生成类const枚举的使用方案
    如果需要和枚举一致的使用体验,可以直接基于提取的类型生成常量对象,编译后和const枚举效果一致,不需要重复维护枚举值:

    const d = [{id: 'Cat'}, {id: 'Dog'}] as const;
    type ids = typeof d[number]['id'];
    
    // 基于数组自动生成常量映射,和const枚举使用方式完全一致
    const IdEnum = Object.fromEntries(d.map(item => [item.id, item.id])) as Record<ids, ids>;
    // 使用:IdEnum.Cat 类型为'Cat',值为'Cat';IdEnum.Dog 类型为'Dog',值为'Dog'
    

注意:如果不加as const或者const类型参数,TypeScript会默认把数组里的id类型拓宽为string,最终提取出的ids类型会是string,无法拿到精确的字面量联合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:48:15