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

TypeScript映射类型keyof返回string|number问题咨询

问题解答

1. number类型的来源

这不是TypeScript的Bug,是官方有意的设计行为,根源在于JavaScript的对象键处理规则:

  • 在JS中,所有对象键最终都会被隐式转换为字符串类型。比如写obj[123],实际等价于obj["123"]。
  • TypeScript为了兼容这种JS原生行为,当你使用字符串索引签名{ [key: string]: string }时,keyof会同时包含string和number类型——毕竟数字类型的键在JS里是合法的,只是会被隐式转成字符串,TS需要覆盖这种使用场景。

2. 通用解决方案

方案一:过滤number类型的键

如果你的场景只需要纯字符串键,可以用Exclude工具类型把number从键类型中剔除:

type StrictStringKey<T> = Exclude<keyof T, number>;

type Test = StrictStringKey<{ [key: string]: string }>;
// Test = string

方案二:修正objectKey函数的类型安全问题

你的objectKey函数存在潜在的类型不匹配问题:Object.keys()在TS中固定返回string[](因为JS对象可能包含超出类型定义的额外键),直接赋值给Array<keyof T>不符合TS的类型规则。可以调整为:

function objectKey<const T extends Record<string, unknown>>(object: T): StrictStringKey<T>[] {
  return Object.keys(object) as StrictStringKey<T>[];
}

方案三:开启严格编译选项

开启--strict(包含noImplicitAny等一系列严格检查规则),可以让TS在类型不兼容时给出更明确的提示,但无法直接改变keyof对字符串索引签名的处理逻辑。

3. 是否属于TypeScript的Bug?

不属于Bug,这是TS为了兼容JavaScript对象键的隐式转换规则特意做的设计,官方文档中明确说明:字符串索引签名的keyof结果会包含string | number类型。

内容的提问来源于stack exchange,提问作者ST-DDT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:40:15