开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情
索引签名
当我们并不清楚除具体的属性名和个数,但想确定属性类型的时候,可以通过索引签名来定义,如
type IndexS = {
[key: string]: string
}
上面代码定义了IndexS对象类型,指定属性名和属性值都为string类型,其中key可以为任意值。假如指定属性名为number类型,则可以理解为表示一个字符串数组,如
type IndexS2 = {
[key: number]: string
}
let stringArr:IndexS2 = ['1','2','3']
索引签名属性取值类型
索引签名的属性名可以指定为string,number,symbol,"template string patterns"(这个类型我不是太理解)以及上面几种类型的组合类型
索引签名注意事项
- ts允许同时定义多种索引签名类型,但应注意,同时指定索引签名属性为number和string类型时,number对应的属性值类型应是string对应的属性的子类型。如
interface Animal {
name: string
}
interface Dog extends Animal {
breed: string
}
type IndexSignature = {
[key:string]: Animal;
[key: number]: Dog
}
let is:IndexSignature = {
"str": {
name: "name"
},
0: {
name: "name",
breed: "breed"
} as Dog
}
上面我们创建了IndexSignature类型,指定其属性名可以为string或number类型,但指定为number类型的属性名对应的属性值类型(Dog)必须是string类型对应的属性值(Animal)的子类。原因是js会自动将number类型的属性名转化成字符串类型。下面附上ts官方解释:
It is possible to support both types of indexers, but the type returned from a numeric indexer must be a subtype of the type returned from the string indexer. This is because when indexing with a
number, JavaScript will actually convert that to astringbefore indexing into an object. That means that indexing with100(anumber) is the same thing as indexing with"100"(astring), so the two need to be consistent.
- “索引签名”要求所有属性对应的属性值类型要满足“索引签名”定义的属性值类型,如
type IndexSignature = {
[key: string]: string;
age: number // Property 'age' of type 'number' is not assignable to 'string' index type 'string'
}
上面IndexSignature限制了属性值为字符串类型,则不允许定义number类型得age属性。若想同时定义属性值为number或string类型,可使用组合类型,如
type IndexSignature = {
[key: string]: string | number;
age: number
}