索引类型

  1. 实现一个pick函数,函数可以从对象上取出指定的属性,在js中应该是这样
    1. function pick(o, names) {
    2. return names.map(o => o[n])
    3. }
    4. // 从user中对象中取出id
    5. const user = {
    6. username: 'garen',
    7. id: '123456',
    8. token: 'abcefg',
    9. role: 'admin'
    10. }
    11. const id = pick(user, ['id'])
    12. console.log(id) ;// 123456
    在TS中实现pick函数, ```typescript // 第一版 interface Obj {
  1. [key: string]: any;

}

function pick(o: Obj, names: string[]) { return names.map(o => o[n]) } // 类型定义不严谨, 参数names的成员应该是参数o的属性, // pick函数的返回值是any[], 应该是所取属性值的联合类型

  1. 如何定义更精准的类型,必须使用索引类型查询操作符和索引访问操作符
  2. <a name="094LX"></a>
  3. ## 索引类型查询操作符
  4. keyof, 作用于泛型T上获取泛型T上的所有public属性名构成联合类型
  5. ```typescript
  6. class Images {
  7. public src: string = 'xxx.xxx.com/yyy.png'
  8. public alt: string = '百度'
  9. public width: number = 500
  10. }
  11. type propNames = keyof Images; // alt|src|width

索引访问操作符

keyof 可以查询索引类型的属性名,访问类型的操作符也是通过 [] 访问, 即T[K];
上面的例子,已经取出的属性名propsNames, 然后通过类型访问的操作符获取值的类型

  1. class Images {
  2. public src: string = 'xxx.xxx.com/yyy.png'
  3. public alt: string = '百度'
  4. public width: number = 500
  5. }
  6. type propNames = keyof Images; // alt|src|width
  7. type propTypes = Images[propNames]

有了这两个操作符,重新实现pick函数

  1. function pick<T, K extends keyof T>(o: T, names: K[]): T[K][] {
  2. return names.map(n => o[n])
  3. }
  4. const res = pick(user, ['token', 'id'])

映射类型

把user接口中的成员全部变成可选了,映射类型适用于这种场景,语法是 [ K in Keys]
K: 类型变量,依次绑定到每个属性上,对应每个属性名的类型
Keys: 字符串字面量构成的联合类型,标识一组属性名(的类型)

  1. interface User {
  2. username: string
  3. id: number
  4. token: string
  5. avatar: string
  6. role: string
  7. }
  8. type partial<T> = { [K in keyof T]?: T[K] }
  9. type partialUser = partial<User>

小结

  1. 索引类型,结合泛型使用
    1. 索引查询操作符, keyof, K extends keyof T
    2. 索引访问操作符, [], T[K]
  2. 映射类型, [ K in Keys ], [ K in keyof T]