TypeScript 索引签名怎么用

日常写代码时,你肯定遇过这种情况:想做一个“存任意用户信息的盒子”,比如可以存姓名、电话、地址,还能加自定义的备注。用普通的JavaScript写,随便加属性就行,但换用TypeScript,要是没做好类型约束,很容易写出“明明存了年龄,编译器却不报错,实际运行还出问题”的代码。这时候索引签名就能帮你解决问题。

先搞懂:索引签名是啥?

简单说,它就是给TypeScript的对象,定了个“属性规则”——不管你加什么属性,必须符合这个规则。举个生活化的例子:你家小区的快递柜,每个柜子的编号(就是属性名)是数字,里面放的包裹(属性值)必须是生鲜。那你设置快递柜规则的时候,就相当于给对象定义了数字类型的索引签名,值只能是string(比如“生鲜包裹”)。

TypeScript 索引签名怎么用

怎么用基础索引签名?

先看最常用的场景:存键值对类型统一的对象。比如做一个“学生成绩表”,属性名是科目名(字符串),属性值是分数(数字),用索引签名可以这么写:

`typescript

// 索引签名:属性名是字符串,属性值是数字

type ScoreTable = {

[subject: string]: number;

};

// 这样写就没问题

const mathScore: ScoreTable = { 数学: 95, 语文: 90 };

// 要是写了数学: "优秀",编译器直接报错,不用等运行才发现

`

这里的[subject: string]: number就是索引签名,它告诉TypeScript:这个类型的对象,不管加什么属性,键得是字符串,值得是数字。

进阶:混合固定属性+索引签名

有时候你需要“基础属性+自定义属性”,比如学生表必须有固定的“学号”属性(字符串),还能加任意科目成绩。这时候可以同时写固定属性和索引签名:

`typescript

type Student = {

// 固定属性:必须有,类型是字符串

studentId: string;

// 索引签名:其他属性是数字

[subject: string]: number | string;

};

const zhang: Student = {

studentId: "2024001", // 固定属性必须有

数学: 95, // 自定义属性,符合索引规则

备注: "偏科生", // 值可以是字符串,因为索引签名是number | string

};

// 要是漏了studentId,或者加了个属性值是布尔的,编译器都会提示错误

`

这里要注意:固定属性的类型,得兼容索引签名的类型。比如索引签名是number,那固定属性不能是string,不然类型冲突。

避坑2个常见错误

第一个坑:索引签名的类型不能是“字面量”。比如你想定义键只能是“数学”“语文”,用[subject: "数学" | "语文"]是错的,TypeScript不允许索引签名用联合字面量,这时候应该用另一种方式(比如Record类型),不过日常写代码用字符串或数字当键就足够灵活了。

第二个坑:索引签名的属性值不能是void类型。比如[key: string]: void是无效的,因为void表示没有值,存东西的对象没必要用这个。

总之,索引签名就是给对象加了个“类型公约”,让你在写动态属性的时候,既能灵活加内容,又能避免类型混乱,不用再靠console.log查错,写代码更省心。

上一篇 PHP 如何做水印