需求
对一个未知的ts嵌套对象类型,想筛选出未知层次的某个属性的值类型,如果不存在返回never
- 如下,一个嵌套的类型定义
type Person = {
name: string,
age: number,
family: {
wife: {
name: string,
beauty: boolean,
hobby: {
buyBuyBuy: {
level: number
},
eatEatEat: {
what: string
}
}
},
self: {
name: boolean,
smart: {
level: string
}
}
}
}
- 想要筛选出hobby或者what等等其他类型
实现
type DeepPick<T, K = string> = K extends keyof T
? T[K]
: { [SubK in keyof T]: T[SubK] extends object ? DeepPick<T[SubK], K> : never }[keyof T];
- 释义
- 类型未知、key未知,显然要使用使用泛型
- 最理想的情况,key就在根属性上,直接返回
- 否则采用递归思路,对每一个属性值进行判断,如果是对象类型,递归筛选。
- 重点
{ [SubK in keyof T]: T[SubK] extends object ? DeepPick<T[SubK], K> : never }[keyof T]这句代码只是为了筛选出
DeepPick<T[SubK], K>,不是太好理解,看看等价的下边的示例就明白了有如下类型:
type Animal = {name: {first: string, second: string}, age: number}用上述的示例组合:type Test = {[K in keyof Animal]: Animal[K] extends object ? Animal[K] : never}结果如下:
我们只是把值不为object的值类型标记为了never,但是我们还需要把值为object的类型筛选出来,所以还需要加上
[keyof Animal]把非never的key筛选出来并得到对应的值类型
回到最初
- 通过DeepPick筛选eatEatEat的类型
- 如果想选择self下的name呢?