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

如何在TypeScript中为可索引类型的键创建字符串字面量类型?

解决TypeScript索引类型提取具体字符串键字面量的问题

为什么keyof typeof myRecords失效?

你的MyRecords是索引签名类型,当给myRecords显式标注MyRecords类型时,TypeScript会丢弃对象的具体键名信息,只保留索引签名的约束。此时typeof myRecords的类型就是MyRecords本身,keyof MyRecords的结果是string | number,自然无法得到你想要的'foo' | 'bar'字面量类型。

正确的实现方式

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

satisfies可以确保对象符合目标类型,但同时保留自身的字面量类型信息,完美适配你的需求:

export type MyRecords = { [name: string]: string | number };

// 用satisfies确保对象符合MyRecords,同时保留具体键的字面量类型
const myRecords = {
  foo: 'a',
  bar: 1,
} satisfies MyRecords;

type KeysOfMyRecords = keyof typeof myRecords; // 类型为 'foo' | 'bar'

const key: KeysOfMyRecords = 'foo'; // 合法
const invalidKey: KeysOfMyRecords = 'invalid'; // 类型错误,符合预期

方法2:泛型约束兼容低版本TS

如果你的TypeScript版本低于4.9,可以用泛型函数来保留字面量类型,同时约束对象符合MyRecords:

export type MyRecords = { [name: string]: string | number };

// 泛型函数约束输入对象符合MyRecords,同时返回原字面量类型
const createRecords = <T extends MyRecords>(obj: T) => obj;

const myRecords = createRecords({
  foo: 'a',
  bar: 1,
});

type KeysOfMyRecords = keyof typeof myRecords; // 类型为 'foo' | 'bar'

总结

核心问题在于显式标注索引类型会丢失具体键的类型信息,通过保留对象的原始字面量类型(同时确保符合索引类型约束),就能提取出你需要的字符串键字面量类型。

内容的提问来源于stack exchange,提问作者cyrus-d

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:35:03