如何从外部导入的JavaScript对象推断常量字面量类型
问题:从外部不可修改JS对象获取字面量类型
我在一个无权修改的外部文件中有如下JavaScript常量对象:
const obj = { prop1: 'val1', prop2: 'val2', }
我希望在TypeScript中基于该对象的属性值定义字面量类型,比如用于函数重载:
function func(key: typeof obj.prop1): string; function func(key: typeof obj.prop2): number;
但导入后TypeScript默认推断obj.prop1和obj.prop2的类型都是string,而非期望的'val1'和'val2'。我试过两种思路但都有局限:
- 给原文件加JSDoc注解标记为const导出,但无权修改原文件;
- 在TS文件中重新定义enum,但值可能和原文件不同步。
可行解决方法
方案1:as const断言配合类型提取
无需修改原文件,在TS侧通过类型断言将导入的对象转为只读字面量类型,再提取属性的精确字面量类型:
// 导入外部对象 import obj from './external-file.js'; // 将对象断言为const类型,锁定字面量值 type Obj = typeof obj as const; type Prop1Type = Obj['prop1']; // 类型为 'val1' type Prop2Type = Obj['prop2']; // 类型为 'val2' // 基于字面量类型定义函数重载 function func(key: Prop1Type): string; function func(key: Prop2Type): number; function func(key: Prop1Type | Prop2Type): string | number { return key === 'val1' ? '对应val1的结果' : 123; }
方案2:使用satisfies关键字(TypeScript 4.9+)
针对TS 4.9及以上版本,用satisfies验证对象结构的同时保留字面量类型推断,再结合as const锁定类型:
import obj from './external-file.js'; // 定义匹配原对象结构的基础类型 type ObjShape = { prop1: string; prop2: string; }; // 验证obj符合结构,且不破坏字面量推断 const typedObj = obj satisfies ObjShape; type TypedObj = typeof typedObj as const; type Prop1Type = TypedObj['prop1']; // 'val1' type Prop2Type = TypedObj['prop2']; // 'val2'
方案3:通用字面量类型提取工具
编写自定义类型工具,自动将对象属性转为对应字面量类型:
// 通用类型工具:提取对象的字面量类型 type Literalize<T> = { [K in keyof T]: T[K] extends string ? `${T[K]}` : T[K] extends number ? `${T[K]}` : T[K]; } as const; import obj from './external-file.js'; type ObjLiteral = Literalize<typeof obj>; type Prop1Type = ObjLiteral['prop1']; // 'val1' type Prop2Type = ObjLiteral['prop2']; // 'val2'
内容的提问来源于stack exchange,提问作者gaurav5430
相关产品推荐
相关产品推荐

