考虑定义如下 TypeScript 代码:
interface NumbersNames {
[key: string]: string
}
const names: NumbersNames = {
1: 'one',
2: 'two',
3: 'three',
// etc...
}
虽然我们定义对象的 key 是数字,但对象会隐式转换为字符串的,当我们通过字符串索引,就能够得到正确的值:
const one = names['1']; // OK
如果通过数字索引呢,就像下面这样:
const two = names[2];
根据上面定义的类型我们知道,我们定义的索引签名是字符串,如果通过数字来进行索引,毫无疑问在 TypeScript 中是错误的。
但真实情况却不是这样,数字索引通过了 TS 的检查,这是为什么?
这是因为数字用作属性访问器中的键时,JavaScript 会隐式将数字强制转换为字符串(names[1]
等价于names['1']
),TypeScript 中也保留这个特性。
知道这个特性有什么用处呢,一个真实的场景是,你需要为一个变量定义类型,这个变量的类型既可以是数组又可以是对象,正常思路应该是这样的:
interface recordable<T = any> {
[key: string | number]: T;
}
当·T = any·,并且你知道上面那个知识点就明白 number 是可以省略的。
interface recordable<T = any> {
[key: string]: T;
}
参考: