11、TS中的索引器

332 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

TS 中的索引器可以给创建的类动态的增加成员

有这样一块代码

const pid: string = 'userId'
class User {
    name: string = 'userName'
    age: number = 18
}
const user = new User()

可以通过 js 中的属性表达式赋值: xxx[xx] = xxx

user['name'] = '用户名'

现在我想给 user 添加 userId 的属性

user[pid] = 123

这句代码其实是有隐患的, 因为 TS 是严格的类型检查怎么能随便的添加没有声明的新属性, 为了防止这种错误可以在tsconfig.json配置文件中加入 compilerOptions.noImplicitAny : true 配置, 添加之后就会报如下错误

image.png

但是有时候确实会动态的增加新属性, 但是又不希望报错怎么办?

索引器

TS 索引器的作用

  • 在严格的检查是, 可以实现为类动态增加成员

  • 可以实现动态的操作类成员

使用: 在类的最前面写上 [属性名: 类型]: 值类型

class User {
    [props: string]: string  //User类的键值对的 键: string 值:string
    name: string = 'userName'
    age: number = 18 //这一行就会提示错误 它不符合上面的约束
    //为了不提示错误可以改为  [props: string]: any
}

有了类第一行的约束, 就可以实现动态的增加属性而不会提示错误

可以书写多行的索引器

可以这样写

class User {
    [props: string]: string
    [props: number]: string
    name: string = 'userName'
}

但是不能这样写

class User {
    [props: string]: string
    [props: number]: number //这一行将会提示错误 “number”索引类型“number”不能分配给“string”索引类型“string”。
    name: string = 'userName'
}

为什么上面这一行会提示错误?

因为在 JS 中键值对的键本质上就是 string 类型, 如果使用数字作为成员名, 还自动转为字符创 [props: number]: number 本质上就是 [props: string]: number 所以就会提示 (“number”索引类型“number”不能分配给“string”索引类型“string”)

总结

这一篇只是很短, 也很简单也能体现出 TS 的用心良苦思考的方方面面几乎覆盖了开发中 99% 遇到的类型检查。