TypeScript中使用Record<string>赋值数字值、Record<string, MyUser>使用数字键均未报错的原因咨询
这两个问题其实都和TypeScript对Record类型的设计,以及JavaScript对象键的本质特性有关,我来逐个给你掰扯清楚:
Record<string>类型时,赋值数字值却未报错? 首先得明确:Record是TypeScript提供的工具类型,完整用法是Record<键类型, 值类型>,用来定义一个键和值都符合指定类型的对象。
你可能没注意到,TypeScript在实现Record时,给第二个泛型参数(值类型)设置了默认值unknown。也就是说,当你只写Record<string>的时候,它等价于Record<string, unknown>。
而unknown是TypeScript的"万能接收"类型——任何类型的值都可以赋值给unknown类型的变量,数字自然也不例外。这就是为什么你给Record<string>赋值数字不会触发报错的原因。
如果想要限制值的类型,你得明确写出第二个参数,比如Record<string, number>(值只能是数字),或者Record<string, string>(值只能是字符串),这样再赋值其他类型就会立刻报错了。
Record<string, MyUser>,但用数字类型的v.id作为键却未报错? 这个得从JavaScript的底层行为说起:JavaScript里对象的键只能是字符串或者Symbol类型,根本不存在数字类型的键。当你尝试用数字作为键时,JS会自动把这个数字转换成对应的字符串(比如数字2会被转成字符串"2")。
TypeScript的类型系统是完全贴合JS运行时行为的,所以它会识别这种隐式转换逻辑。当你在代码里写[v.id]作为对象的键时,TypeScript清楚最终运行时这个键会变成字符串,而Record<string, MyUser>要求的键就是字符串类型,两者完全匹配,所以不会触发类型错误。
举个例子,你的代码里v.id是数字2,最终生成的对象键其实是字符串"2",和Record<string, MyUser>的定义完全一致,类型检查自然就通过了。
内容的提问来源于stack exchange,提问作者universe11

