Home > Enterprise >  I'm looking for a `PickOptional<T, K>` generic
I'm looking for a `PickOptional<T, K>` generic

Time:10-27

Below I have an interface and I am picking sounds off of it, I'd like a generic that replaces pick / wraps it to 1) take any string key (currently type error on 'cluck' and 2) not put unknown properties, just simply leave it out.

interface Sounds {
    'meow': true
    "woof": false
}

type Sound = Pick<Sounds, 'woof' | 'cluck'>
//                                    /.\
//                                     |
// type Sound = {                  This throws 
//     woof: false;                    
//     cluck: unknown; <!--- I don't want this
// }

CodePudding user response:

Using Pick<Type, Keys> with Extract<Type, Union> to filter out the unwanted keys:

interface Sounds {
    meow: true;
    woof: false;
}

type PickOptional<T, U> = Pick<T, Extract<U, keyof T>>;  

type Sound = PickOptional<Sounds, 'woof' | 'cluck'>;

/* Evaluates to: 
type Sound = {
  woof: false;
}
*/

CodePudding user response:

I would propose to create an intermediate Pick type, using conditional types.

interface Sounds {
    'meow': true
    "woof": false
}

type PickIfExists<T, U> = Pick<T, U extends keyof T ? U : never>
type Sound = PickIfExists<Sounds, 'woof' | 'cluck'>

// type Sound = {
//   woof: false;
// }

Test it on Typescript Playground.

  • Related