索引签名允许你定义对象的键和值的类型约束。通过索引签名,可以确保对象的动态属性名和属性值符合指定的类型规则。索引签名分为字符串索引签名和数字索引签名两种核心类型。
字符串索引签名用于约束对象的属性键为字符串类型,所有字符串键对应的属性值必须遵守约定的类型。 这是开发中最常用的索引签名,适用于动态键名的普通对象。
interface StringIndexedObject {
// 字符串索引签名:键为 string,值为 number
[key: string]: number;
}
const example: StringIndexedObject = {
apple: 1,
banana: 2,
};
// 合法:动态添加字符串键
example.orange = 3;
// 报错:值类型不匹配
// example.grape = "error";在这个例子中:
[key: string]: number是标准的字符串索引签名对象的所有字符串类型的键,对应的值必须是 number 类型
无论是初始赋值还是动态添加属性,都会受到严格的类型约束
数字索引签名用于约束对象的属性键为数字类型,所有数字键对应的属性值必须遵守约定的类型。 在 JavaScript 中,数字键会被自动转换为字符串,但 TypeScript 会严格校验索引类型。
interface NumberIndexedObject {
// 数字索引签名:键为 number,值为 string
[key: number]: string;
}
const example: NumberIndexedObject = {
1: 'one',
2: 'two',
};
// 合法:数字键赋值
example[3] = 'three';
// 报错:值类型不匹配
// example[4] = 4;补充:JavaScript 数组的本质就是数字索引签名,
string[]等价于{ [index: number]: string }。
TypeScript 支持同时定义字符串和数字两种索引签名,但有强制语法规则: 数字索引签名的值类型,必须是字符串索引签名值类型的子类型。 这是因为 JavaScript 会将数字键自动转为字符串,TypeScript 需要以此保证类型安全。
interface MixedIndexedObject {
[key: string]: string | number;
[key: number]: string;
}
const example: MixedIndexedObject = {
1: 'one',
2: 'two',
'apple': 1,
'banana': 'yellow'
};在这个例子中:
数字索引的值类型
string是字符串索引值类型string | number的子类型,符合 TS 强制规则对象可同时包含数字键和字符串键,且值类型完全满足约束要求
固定属性兼容规则 接口内的显式属性,类型必须兼容索引签名的值类型,否则会报错
只读索引签名 可搭配 readonly 限制属性不可修改:readonly [key: string]: number
约束范围 一旦定义索引签名,对象的所有属性都必须遵循该签名的类型规则
Record<K, T> 是 TypeScript 内置的泛型工具类型,底层基于索引签名实现,是索引签名的简化语法糖:
// 两种写法完全等价
type Obj1 = Record<string, number>;
type Obj2 = { [key: string]: number };核心作用:索引签名用于约束动态键名对象的键类型和值类型;
两种形式:字符串索引(常用)、数字索引(数组底层实现);
混合规则:数字索引的值类型必须是字符串索引值类型的子类型;
语法糖:Record 类型是索引签名的简化写法,二者功能完全一致。