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

TypeScript中如何通过keyof typeof获取对象键精确联合类型

问题根源

你当前写法无法得到精确键联合的核心原因是:显式给myConfs标注带字符串索引签名{ [k: string]: (myArg: { name: string }) => string }的类型后,TypeScript会直接将变量类型收窄为这个宽泛的索引类型,丢失对象字面量本身的具体键信息,此时keyof typeof myConfs得到的结果自然是string,无法对赋值做精确校验。
如果直接移除显式类型标注,TS虽然能推导出精确的键字面量联合,但失去了对每个属性对应回调函数的类型约束,两种写法都无法同时满足「约束值类型」和「保留精确键类型」两个需求。

实现方法

TS 4.9+ 推荐方案:使用satisfies运算符

satisfies是TS 4.9版本新增的关键字,作用是校验表达式是否匹配指定类型,但不改变表达式本身的推导类型,完全匹配当前场景的需求:

const myConfs = {
  'Hello': ({ name }) => `World from ${name}`,
  'Goodbye': ({ name }) => `World from ${name}`,
} satisfies { [k: string]: (myArg: { name: string }) => string };

type MyKeys = keyof typeof myConfs; // 推导结果为 "Hello" | "Goodbye"

// 此处会按预期抛出类型错误:Type '"hello"' is not assignable to type '"Hello" | "Goodbye"'
const key: MyKeys = 'hello';

这个写法的优势:

  • 自动校验myConfs下所有属性的回调是否符合签名要求,如果参数类型、返回值类型写错,TS会直接在对应属性位置抛出错误
  • 完全保留对象字面量的键值推导结果,不会把键拓宽为string类型

低版本兼容方案:泛型辅助函数

如果你的项目TS版本低于4.9,无法使用satisfies,可以通过泛型辅助函数实现相同效果,利用泛型推导保留具体键类型,同时约束值的类型符合要求:

// 定义泛型构造函数
const defineMyConfs = <T extends string>(
  confs: Record<T, (myArg: { name: string }) => string>
) => confs;

const myConfs = defineMyConfs({
  'Hello': ({ name }) => `World from ${name}`,
  'Goodbye': ({ name }) => `World from ${name}`,
});

type MyKeys = keyof typeof myConfs; // 推导结果为 "Hello" | "Goodbye"

// 此处同样会按预期抛出类型错误
const key: MyKeys = 'hello';

内容的提问来源于stack exchange,提问作者Jeggy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:21:31