TypeScript中如何正确为枚举(enum)键数组标注精确类型
问题解答
首先先纠正你现有代码的一个运行时坑:TypeScript的数值枚举默认会生成双向映射,你当前用Object.entries(Fruit).map(f => f[0])拿到的运行时结果实际是['apple', 'banana', '0', '1'],并不是你预期的['apple', 'banana'],需要先加一层过滤逻辑,只保留值为数字的条目对应的键:
export const Fruits = Object.entries(Fruit) // 过滤掉反向映射的数字键条目 .filter(([_, value]) => typeof value === 'number') .map(([key]) => key as keyof typeof Fruit);
回到你的类型问题:
你之前得到的("apple" | "banana")[]并不是能拿到的最精确类型,你可以通过显式类型断言得到你期望的固定元组类型,写法如下:
export const Fruits = Object.entries(Fruit) .filter(([_, value]) => typeof value === 'number') .map(([key]) => key) as ["apple", "banana"];
此时Fruits的类型就是你想要的const Fruits: ["apple", "banana"]。
补充说明
- 目前TypeScript(截止5.4版本)无法自动推导出生成数组的固定长度元组类型,因为
Object.entries、map等数组方法的返回类型默认是动态数组,类型系统无法捕获运行时遍历枚举的成员顺序和数量,所以这个显式断言是必要的。缺点是如果你后续修改了Fruit的枚举成员,需要同步更新这个断言的元组类型,避免类型和运行时结果不一致。 - 如果你完全不想手动维护枚举成员的重复定义,那
("apple" | "banana")[]就是你能得到的最精确的自动推导类型。 - 你代码里
interface Meal定义中的tpeof是笔误,修正为typeof即可正常使用。
内容的提问来源于stack exchange,提问作者Alex Pappas
相关产品推荐
相关产品推荐

