0

I want to define a generic types that makes all properties of a given type that are possibly undefined optional.

Example:

type MyType = {
  a: number | undefined
  b: number
}

I'm looking for a generic type

type OptionalUndefined<MyType>

which should result in

{
  a?: number | undefined
  b: number
}

I tried this, but it's not working:

type OptionalUndefined<T> = {
  [P in keyof T]: T[P] extends undefined ? T[P] | never : T[P]
}

Any ideas how to achieve this?

Reducer
  • 670
  • 7
  • 14

1 Answers1

3

You need to construct the final type as an intersection between an object type with the optional properties, and an object type containing the rest of the proeprties.

You can filter the undefined keys, using a similar approach to here. With the undefined keys you can Pick them from T and make the optional using Partial, to get the object type with the optional properties. On the other side you can use Omit to omit the undefined properties from T

type MyType = {
  a: number | undefined
  b: number
}


type UndefinedKeys<T> = {
    [P in keyof T]: undefined extends T[P]  ? P: never
}[keyof T]

type OptionalUndefined<T> = Partial<Pick<T, UndefinedKeys<T>>> & Omit<T, UndefinedKeys<T>>
type Id<T> = {} & { [P in keyof T] : T[P]}
type X = Id<OptionalUndefined<MyType>>
// type X = {
//     a?: number | undefined;
//     b: number;
// }

Playground Link

Note: Id is used to flatten the resulting type, while this is not necessary it can be useful to make the type easier to read.

Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357