索引签名
在js中ES6允许用表达式作为对象的属性名,但是一定要将表达式放在方括号内。会把表达式使用toString()方法,这样js中对象和函数等也可以作为索引。而ts 做了进一步的约束,索引类型只能是:string | number | symbol
,而value
可以是任意类型。
索引签名的名称如
[index:number]:string
里的index
只是占位符并无任何意义,可以是任意单词。
索引签名就是在约束了索引(key
)类型的基础上,统一定义了对象的 key
和 value
的类型 。换句话说,索引签名可以在只知道key
和value
的类型下,来统一定义对象的类型。
当声明一个索引签名后,所有成员的key和value都必须符合索引签名
js
interface Sign1 {
// key 只是占位符
[key: string]: string;
}
type Sign2 = {
[index: number]: string | number;
};
const foo: {
[aaa: string]: { message: string }; // value 只能是1个对象,并且只有1个属性 message
} = {};
定义了索引签名,那么确定属性和可选属性的类型都必须是它的类型的子集
js
type attentionType{
name: string; // 编译通过
age?: number; // 编译报错:类型"number | undefined"的属性"age"不能赋给"string"索引类型"string"。ts(2411)
sex?: undefined; // 编译通过
[propName: string]: string | undefined;
}
在多个索引签名存在时,
string
类型的索引最严格,书写时应该包含所有的 value 类型。其他类型的索引,对应的 value 类型只能是string
类型的value类型的子级
js
interface Sign3 {
[key: string]: string | number | boolean;// 必须包括所用成员类型
[index: symbol]: string;
[index2: number]: number;
}
js
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
interface NotOkay {
[x: string]: Dog;
[x: number]: Animal; // Error
}
interface Okay {
[x: string]: Animal;
[x: number]: Dog; // OK
}