Home > Mobile >  TS: Construct type from optional properties of interface
TS: Construct type from optional properties of interface

Time:04-12

Supposing we have a similar interface:

interface Interface {
  foo: string;
  bar: number;
  baz?: boolean;
}

How can we construct a type with only its optional properties?

With the interface above, I'd be looking to something like:

interface PartialInterface {
  baz: boolean;
}

A solution would be of course to use either Omit or Pick; That would work on small interfaces, but it wouldn't really be suitable for bigger scenarios.

Any suggestion is highly appreciated, thank you in advance!

CodePudding user response:

We'll combine the removal of the ? modifier using the - prefix and filtering properties with the as keyword in mapped types:

type PickOptionals<T> = {
    // `Interface` below extends
    //   `Record<"foo", string>` and
    //   `Record<"bar", number>` but not
    // - `Record<"baz", boolean>`.
    // Since the right side of `as` evaluates to `never` when
    // `K` is "foo" or "bar", those properties are dropped entirely.
    [K in keyof T as T extends Record<K, T[K]> ? never : K]-?: T[K];
}

interface Interface {
  foo: string;
  bar: number;
  baz?: boolean;
}

type PartialInterface = PickOptionals<Interface>
// = { baz: boolean }

Here's a playground link for good measure

  • Related