TypeScript 4.8.2中不使用as const获取常量字面量类型的方法问询
解决方案
核心思路
你的常量已被标注为KeyValue[],TypeScript会丢失具体的字面量信息,直接通过typeof无法获取原始key的字面量类型。要在不破坏现有类型系统(即常量对外仍保持KeyValue[]类型)的前提下捕获字面量信息,需借助泛型函数在定义常量时保留原始字面量类型。
实现步骤
- 定义泛型工具函数,创建常量时捕获字面量类型,同时对外返回
KeyValue[]类型:
// 假设你的 KeyValue 基础类型定义如下 type KeyValue = { key: string; value: string }; // 泛型函数:捕获输入的字面量类型,对外返回宽泛的 KeyValue[] 类型,不影响现有代码使用 const createConstants = <T extends KeyValue[]>(constants: T): KeyValue[] => constants;
- 用该函数定义常量(若为已存在的常量,仅修改定义方式即可,对外类型仍为
KeyValue[],不会破坏现有依赖):
// 原定义:const constants1: KeyValue[] = [...] // 修改后定义,对外类型不变,但内部已捕获字面量类型 const constants1 = createConstants([ { key: 'key1', value: 'val1' }, { key: 'key2', value: 'val2' } ]); const constants2 = createConstants([ { key: 'key3', value: 'val3' }, { key: 'key4', value: 'val4' }, { key: 'key5', value: 'val5' } ]);
- 提取key的联合类型:
// 从 constants1 提取key字面量联合类型 type Constants1Keys = typeof constants1 extends ReturnType<typeof createConstants<infer T>> ? T[number]['key'] : never; // 从 constants2 提取key字面量联合类型 type Constants2Keys = typeof constants2 extends ReturnType<typeof createConstants<infer T>> ? T[number]['key'] : never; // 合并两个常量的key类型 type AllValidKeys = Constants1Keys | Constants2Keys; // 最终得到 'key1'|'key2'|'key3'|'key4'|'key5'
- 在自定义类型中使用:
type CustomType = { validKey: AllValidKeys; // 其他字段... };
为什么之前的尝试不生效?
你之前写的((typeof constants1) as const)[number]['key']无效,是因为typeof constants1已经是宽泛的KeyValue[]类型,即使添加as const也无法将string类型还原为原始字面量——TypeScript在类型推断阶段已经丢失了这部分信息,必须在定义常量时通过泛型提前捕获。
内容的提问来源于stack exchange,提问作者Ravi Teja Vattem
相关产品推荐
相关产品推荐

