TypeScript: 如何为对象动态分配属性

前端人

共 2716字,需浏览 6分钟

 ·

2021-08-12 18:29

鬼哥本周将通过几篇优秀的Typescript文章,让大家学习到Typescript一些高级的用法,让大家对Typescript更加的深入理解,并且更好实践到工作当中,【一共五篇文章】,关注我们一起完成这个系列的学习

原文:https://github.com/leslie1943


  • 在JavaScript中我们很容易给对象动态添加属性
let developer = {}
developer.name = 'frontender'  
  • 以上代码在 JavaScript 中可以正常运行, 但在 TypeScript 中, 编译器会提示以下异常信息
Property 'name' does not exist on type '{}'.ts(2339)

🚀🚀🚀 使用 索引签名

  • {}类型表示一个没有包含成员的对象, 所以该类型没有包含name属性. 为了解决这个问题, 我们可以声明一个 LooseObject类型
interface LooseObject {
  [key: string]: any
}

let developer: LooseObject = {}
developer.name = 'finder'
  • 该类型使用 索引签名 的形式描述 LooseObject 类型可以接收 key 类型是字符串, 值的类型是any类型的字段. 有了LooseObject类型之后, 我们就可以通过上述代码解决动态添加属性的问题

  • 对于 LooseObject 类型来说, 它的约束是很宽松的. 在一些应用场景中, 我们除了希望能支持动态的属性之外, 也希望能够声明一些必选和可选的属性.

  • 比如对于一个表示开发者的 Developer 接口来说, 我们希望它的 name 属性是必填, 而 age 属性是可选的, 此外还支持动态地设置字符串类型的属性. 针对这个需求我们可以这样做

interface LooseStaticObject {
  name: string
  age?: number
  [key: string]: any
}

let coder: LooseStaticObject = { name'semlinker' }
coder.age = 30
coder.city = 'Dalian'

🚀🚀🚀 使用工具类型 Record 定义接口

  • 其实除了使用 索引签名 之外, 我们也可以使用 TypeScript 内置的工具类型 Record 来定义 Developer 接口
// type Record<K extends string | number | symbol, T> = { [P in K]: T; }
// { [P in K]: T } : 属性名称是 string |number | symbol 之一(下面代码中的 string), 属性值是 T 类型(下面代码中的any)

// <K, T>: K 是指属性的类型; T 是指属性的值类型 any指任意类型

interface Developer extends Record<string, any> {
  name: string
  age?: number
}

let developer: Developer = { name'coder'1'1' }
developer.age = 22
developer.city = 'Dalian'

// Record<K,T>中的 💛 T 是 string, Value 只能是 string
interface Coder extends Record<string, string> {
  name: string
  age?: string // 只能是 string
}
let coder: Coder = { name'coder' }
// coder.age = 22 // Type 'number' is not assignable to type 'string'.ts(2322)
coder.age = `22`

关注公众号添加鬼哥微信,和鬼哥一起学习

❤️ 看完三件事

如果你觉得这篇内容对你挺有启发,不妨:

  • 点个【在看】,或者分享转发,让更多的人也能看到这篇内容

  • 点击↓面关注我们,一起学前端

  • 长按↓面二维码,添加鬼哥微信,一起学前端



浏览 142
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报