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

为何数字能作为{ [key: string]: unknown; }的合法键?

问题原因解析

这是因为TypeScript对对象属性名和索引签名的处理逻辑,核心有两点:

  • 数字属性名会被自动转换为字符串:JavaScript中对象的属性名本质都是字符串(Symbol类型除外),所以你写{1: string}在TypeScript的类型系统里,和{"1": string}是等价的,而且允许用数字字面量1或者字符串字面量"1"来访问这个属性。
  • 字符串索引签名兼容数字键:你的泛型约束DataType extends { [_: string]: unknown },并不是说只能有字符串类型的键,而是要求所有属性的类型都符合unknown。由于数字键最终会被转为字符串,所以{ "name": "Tom", 1: string }完全满足这个约束——它的所有属性类型都符合unknown的要求。

再看keyof DataType的结果:对于{"name":"Tom",1:string}这个类型,keyof会返回"name" | 1(同时也兼容"1",因为TypeScript会把数字键和对应的字符串键视为等价)。所以你传入参数1时,完全符合keyof DataType的类型要求,自然不会触发错误。

如果想要禁止数字键作为参数,你可以修改泛型约束,明确排除数字对应的属性名:

// 定义一个只保留非数字字符串键的类型
type StringOnlyKey<T> = T extends string ? (T extends `${number}` ? never : T) : never;

function Foo<DataType extends Record<StringOnlyKey<keyof DataType>, unknown>>(
  name: StringOnlyKey<keyof DataType>
) {
  return name;
}

Foo<{"name":"Tom",1:string}>(1); // 此时会触发错误,符合预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:17:15