前言
索引类型其实包含了三个部分:索引签名类型、索引类型查询与索引类型访问。索引类型与我们JS中的对象息息相关,但是不能混淆,我们在TS的使用中,要时刻记得它是针对类型的编程。
索引签名类型
索引签名类型常用于定义接口和类型别名。举个例子我们想定义一个键值都为String类型的Object我们就可以如下定义:
interface StringType {
[key:string]:string;
}
type StringType = {
[key:string]:string;
}
这时,即使你还没声明具体的属性,对于这些类型结构的属性访问也将全部被视为 string 类型:
type Type1 = StringType['test1']; // string
type Type2 = StringType['123']; // string
它还可以很好的解决我们遍历对象时for...in的报错。像下面这种错误,我们只需要定义一个索引签名类型即刻解决。
注意
由于JS的对象键值只能是字符窜和Symbol类型,所以在上面的例子中StringType['123']和StringType[123]的效果是一致的。也就是说虽然我们定义了键值只能是String类型,但是实际上我们通过传入Number类型的键值也会得到同样的结果。
索引类型查询
索引类型查询需要用到一个操作符-keyof。它的实际作用跟js中的keyof差不多,根据官方文档的说法,它可以将对象中的所有键转换为对应字面量类型,然后再组合成联合类型。值得注意的是,keyof并不会将数字类型的键名转换为字符串类型字面量,而是仍然保持为数字类型字面量,这是与上面的索引签名类型不一样的。
interface Test {
test: 1,
123: 'hhh'
}
type TestKeys = keyof Test; // test|123
索引类型访问
在JS中我们可以通过obj['xxx']的语法去访问一个对象的属性,其中xxx可以是一个表达式,一个变量,或者一个常量。在TS中我们同样可以使用这种语法,不过我们得到的是一种类型。
interface Test {
propA: number;
propB: boolean;
}
type PropAType = Test['propA']; // number
type PropBType = Test['propB']; // boolean
索引类型查询的本质其实就是,通过键的字面量类型访问这个键对应的键值类型 。