logoProsperBao

PickByType

2022-04-11 07

题目来源(type-challenges)

问题

从对象中挑选出指定类型的属性

interface Model {
  name: string
  count: number
  isReadonly: boolean
  isEnable: boolean
}

type case1 = PickByType<Model, boolean> // { isReadonly: boolean; isEnable: boolean }
type case2 = PickByType<Model, string> // { name: string }
type case3 = PickByType<Model, number> // { count: number }

解答

type PickByType<T, U> = {
  [ K in keyof T as T[K] extends U ? K : never ]: U
}

拆分

  1. 可以把索引签名看成两个部分
  2. K in keyof T
  3. T[K] extends U ? K : never
  4. 1.1 是用来索引泛型 T
  5. as 用来断言 KT[K] 的索引签名
  6. 1.2 是用来确认 T[K]U 的类型
  7. 不是 U 类型的直接用 never 过滤掉