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

如何从外部导入的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 01:52:09