21.【TypeScript 教程】索引类型

发布时间:2024年01月19日

TypeScript 索引类型

下面是一个常见的 JavaScript 函数,实现从一个对象中选取指定属性,得到它们的属性值:

function pluck(o, names) {
  return names.map(n => o[n])
}

实现这样一个函数的类型定义要满足:

  • 数组参数?names?中的元素,只能是对象?o?身上有的属性。
  • 返回类型取决于参数?o?身上属性值的类型。

我们可以通过索引类型实现这样的类型定义。

1. 解释

索引类型可以让 TypeScript 编译器覆盖检测到使用了动态属性名的代码。

要理解抽象的索引类型,需要先理解索引类型查询操作符(keyof)和索引访问操作符(T[K])。

2. 索引类型查询操作符 - keyof

keyof?可以获取对象的可访问索引字符串字面量类型。

interface User {
  id: number,
  phone: string,
  nickname: string,
  readonly department: string,
}

class Token{
  private secret: string | undefined
  public accessExp: number = 60 * 60
  public refreshExp: number = 60 * 60 * 24 * 30 * 3
}

let user: keyof User // let user: "id" | "phone" | "nickname" | "department"
type token = keyof Token // type token = "accessExp" | "refreshExp"

代码解释:

倒数第二行,通过?let user: keyof User?得到了等价的?let user: "id" | "phone" | "nickname" | "department"

最后一行,通过?type token = keyof Token?得到了等价的?type token = "accessExp" | "refreshExp",注意这里没有?secret

可以看到对于任何类型?T,?keyof T?的结果为?T?上已知的公共属性名的联合

3. 索引访问操作符 - T[K]

通过?keyof?拿到了属性名,接下来还要拿到属性名对应属性值的类型。

还是以上面的 Token 类为例:

class Token{
  public secret: string = 'ixeFoe3x.2doa'
  public accessExp: number = 60 * 60
  public refreshExp: number = 60 * 60 * 24 * 30 * 3
}

type token = keyof Token
type valueType = Token[token] // type valueType = string | number
type secret = Token['secret'] // type secret = string

代码解释:

通过?Token['secret']?拿到了属性 secret 的类型为 string。

那么这时,我们知道了一个对象的类型为泛型?T,这个对象的属性类型?K?只需要满足?K extends keyof T,即可得到这个属性值的类型为?T[K]

理解了上面这段话,即可定义下面这个函数:

function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
  return o[name]; // o[name] is of type T[K]
}

代码解释:?已知参数 o 的类型为 T,参数 name 的类型 K 满足?K extends keyof T,那么返回值的类型即为?T[K]

4. 函数 pluck() 的类型定义

掌握了 keyof 和 T[K],下面来完整的书写前言中的函数 pluck() :

function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] {
  return names.map(n => o[n])
}

interface Person {
  name: string
  position: string
  age: number
}
let person: Person = {
  name: 'Evan',
  position: 'Software Engineer',
  age: 27
}

let values: unknown[] = pluck(person, ['name', 'age'])
console.log(values)

代码解释:?参数?names: K[]?这种写法表示数组类型。

5. 小结

本节介绍了高级类型中的索引类型,理解起来可能比较抽象,需要多加练习。

文章来源:https://blog.csdn.net/u014316335/article/details/135691100
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。