【TypeScript】索引签名类型(Index Signatures)
索引签名类型
索引签名(Index Signatures)允许定义对象中动态属性名的类型规则,特别适合处理键值对集合或不确定属性名的对象结构。
🏷️ 基本语法
interface Dictionary {[key: string]: number; // 字符串索引签名
}interface NumericDictionary {[index: number]: string; // 数字索引签名
}
🌟 核心特性
1. 字符串索引签名
interface StringKeyObject {[key: string]: any; // 允许任意字符串作为键name: string; // ✅ 可以包含已知属性(必须符合索引签名约束)
}const obj: StringKeyObject = {name: "Alice",age: 30, // ✅ 符合 [key: string]: any"favorite-color": "blue"
};
2. 数字索引签名
interface NumberKeyArray {[index: number]: string; // 类似数组的结构length: number; // 可以包含其他属性
}const arr: NumberKeyArray = {0: "first",1: "second",length: 2
};
3. 混合索引签名
interface HybridDictionary {[key: string]: string | number;[index: number]: string; // 数字索引返回值必须是字符串索引的子类型id: number; // 已知属性必须符合索引签名
}
🛠️ 实际应用场景
1. 动态属性对象
interface DynamicConfig {[setting: string]: boolean | string;debugMode: boolean; // 特定已知属性
}const config: DynamicConfig = {debugMode: true,"feature.autoSave": true,"ui.theme": "dark"
};
2. 类型安全的字典
interface WordDictionary {[word: string]: {definition: string;synonyms: string[];};
}const dictionary: WordDictionary = {"ephemeral": {definition: "lasting for a very short time",synonyms: ["transient", "fleeting"]}
};
3. 模拟数组结构
interface MyArray<T> {[n: number]: T;length: number;push(...items: T[]): number;
}const nums: MyArray<number> = {0: 1,1: 2,length: 2,push: function(...items) { /* 实现 */ }
};
⚠️ 重要限制与注意事项
-
类型一致性规则:
interface Problematic {[key: string]: number;name: string; // ❌ 错误:string 不符合 number }
-
只读索引签名:
interface ReadonlyMap {readonly [key: string]: number; }const map: ReadonlyMap = { count: 1 }; // map.count = 2; ❌ 错误:只读属性
-
与 Record 工具类型的区别:
// 索引签名方式 interface StringToNumber {[key: string]: number; }// Record 方式 type StringToNumber = Record<string, number>;/* 区别:- Record 更简洁- 索引签名可以在接口中与其他属性共存 */
🚀 高级技巧
1. 模板字面量索引签名(TS 4.4+)
interface Headers {[header: `x-${string}`]: string;"content-type": string;
}const headers: Headers = {"x-request-id": "123","x-api-key": "secret","content-type": "application/json"// "auth-token": "xxx" ❌ 不符合模板
};
2. 条件索引签名
type Conditional<T> = T extends "readonly" ? { readonly [key: string]: number } : { [key: string]: number };const readOnlyDict: Conditional<"readonly"> = { count: 1 };
// readOnlyDict.count = 2; ❌ 错误
索引签名是 TypeScript 灵活类型系统的关键特性之一,合理使用可以:
- 处理动态数据结构 🔄
- 保持类型安全 🛡️
- 减少 any 的使用 🚫
- 提高代码可维护性 🧹