如何从对象数组的指定属性生成字符串字面量联合类型
从静态对象数组提取属性字面量联合类型的实现方案
完全可以实现,不需要额外的运行时能力,TypeScript 在编译阶段就能完成该类型推导,只需要调整原有代码的类型定义逻辑即可。
你原有代码无法得到正确类型的问题有两个:
- 给
icons显式标注了readonly Icon[]类型,该类型中name属性是宽泛的string类型,直接覆盖了const断言能推导出来的字面量类型 - 数组内置的
map方法默认返回string[]类型,无法保留字面量联合特性,不需要额外定义tuple函数处理
推荐实现方案(TS 4.9+)
使用satisfies操作符做类型校验,既保证数组中每个对象符合Icon接口结构,又不会擦除const断言推导出来的字面量类型:
<script lang="ts"> interface Icon { name: string color: string } // 用satisfies校验结构符合Icon,同时保留const断言的字面量类型 const icons = [ { name: "close", color: "red" }, { name: "open", color: "blue" } ] as const satisfies readonly Icon[]; // 直接从数组元素的name属性提取联合类型,推导结果为 "close" | "open" type IconName = typeof icons[number]['name']; export let name: IconName; // 非空断言保证类型正确,因为name必然属于IconName,一定能找到匹配项 let displayIcon = icons.find((e) => e.name === name)!; </script> <h1>{displayIcon.color}</h1>
低版本TS兼容方案(<4.9)
如果你的TS版本不支持satisfies操作符,可以用泛型工具函数实现同样的效果:
// 泛型工具函数,校验输入符合Icon[]结构,同时保留输入值的字面量类型 const defineIcons = <T extends readonly Icon[]>(icons: T) => icons; const icons = defineIcons([ { name: "close", color: "red" }, { name: "open", color: "blue" } ] as const);
内容的提问来源于stack exchange,提问作者Jackson Lloyd
相关产品推荐
相关产品推荐

