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

TypeScript中从已定义对象提取键的问题

TypeScript中从已定义对象提取具体键的解决方案

问题场景:当你定义了带字符串索引签名的类型A,并将一个字面量对象赋值给标注为A的常量后,尝试提取键时得到的是string | number,而非预期的具体键名'myKey'。

问题原因

当你给变量显式标注类型A时,TypeScript会优先使用这个标注类型,而非对象字面量的推断类型。keyof A的结果是string | number(JavaScript中对象的数字键会被转换为字符串,TypeScript对字符串索引类型的键定义包含这两种类型),所以即使你用了as const,也无法改变变量的类型为A的事实。

解决方案

方案1:使用satisfies关键字(TypeScript 4.9+)

satisfies可以检查对象是否符合指定类型,但不会覆盖TypeScript对对象字面量的类型推断,既能保证结构合规,又能保留具体键名:

type A = {
  [key: string]: 123,
}

const aTyped = {
  myKey: 123,
} as const satisfies A;

type ExtractKeys<T> = keyof T;

type Keys = ExtractKeys<typeof aTyped>; // Keys = 'myKey'

方案2:分离字面量类型与约束类型

先定义不带类型标注的常量,保留字面量类型,再将其赋值给标注为A的变量:

type A = {
  [key: string]: 123,
}

// 保留字面量类型的原始常量
const aLiteral = {
  myKey: 123,
} as const;

// 标注类型A,不影响原始常量的类型
const aTyped: A = aLiteral;

type Keys = keyof typeof aLiteral; // Keys = 'myKey'

方案3:用泛型函数捕获具体类型

通过泛型函数创建对象,既约束对象符合A的结构,又能捕获具体的字面量类型:

type A = {
  [key: string]: 123,
}

function createA<T extends A>(obj: T) {
  return obj;
}

const aTyped = createA({
  myKey: 123,
} as const);

type ExtractKeys<T> = keyof T;

type Keys = ExtractKeys<typeof aTyped>; // Keys = 'myKey'

内容的提问来源于stack exchange,提问作者Page not found

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:42:53