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