yunliuyan / type-challenges

typescript-challenges
0 stars 2 forks source link

00022-hard-deeppick #22

Open yunliuyan opened 11 months ago

yunliuyan commented 11 months ago

DeepPick hard #deep

by hiroya iizuka @hiroyaiizuka

Take the Challenge

Implement a type DeepPick, that extends Utility types Pick. A type takes two arguments.

For example:


type obj = {
  name: 'hoge', 
  age: 20,
  friend: {
    name: 'fuga',
    age: 30,
    family: {
      name: 'baz',  
      age: 1 
    }
  }
}

type T1 = DeepPick<obj, 'name'>   // { name : 'hoge' }
type T2 = DeepPick<obj, 'name' | 'friend.name'>  // { name : 'hoge' } & { friend: { name: 'fuga' }}
type T3 = DeepPick<obj, 'name' | 'friend.name' |  'friend.family.name'>  // { name : 'hoge' } &  { friend: { name: 'fuga' }} & { friend: { family: { name: 'baz' }}}

Back Share your Solutions Check out Solutions
yunliuyan commented 11 months ago

思路

递归

代码实现

type GetKey<S> = S extends '' ? '' : S extends `${infer L}.${infer R}` ? [L, R] :[S];

type DeepPick<T extends object, U> = {
  [key in keyof T as key extends GetKey<U>[0] ? key : never] : T[key] extends object ? DeepPick<T[key], GetKey<U>[1]> : T[key];
}