Last active
September 19, 2022 16:26
-
-
Save joemaffei/d1ee37ab900cdd63e424d9f6cb855134 to your computer and use it in GitHub Desktop.
Make optional any properties whose types that have a union with null
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Inspired by this article by Rafael Bardini: | |
* {@link https://rbardini.com/making-optional-properties-nullable-typescript/} | |
*/ | |
type NullUnion<T> = T | null; | |
// type NullableProps<T> = { | |
// [K in keyof T]: NullUnion<T[K]> extends T[K] ? K : never; | |
// }[keyof T]; | |
// type NonNullableProps<T> = { | |
// [K in keyof T]: NullUnion<T[K]> extends T[K] ? never : K; | |
// }[keyof T]; | |
// type PickNullable<T> = Pick<T, NullableProps<T>>; | |
// type PickNonNullable<T> = Pick<T, NonNullableProps<T>>; | |
// type NullableToOptional<T> = Partial<PickNullable<T>> & PickNonNullable<T>; | |
/** | |
* Converts any properties that have a union with null into optional properties. | |
* | |
* @example | |
* type Sample = { | |
* propA: string | null; | |
* propB: number | null; | |
* required: boolean; | |
* } | |
* | |
* type Test = NullableToOptional<Sample>; | |
* | |
* type Expected = { | |
* propA?: string | null; | |
* propB?: number | null; | |
* required: boolean; | |
* } | |
* | |
* // types Test and Expected are equivalent. | |
*/ | |
type NullableToOptional<T> = Partial<Pick<T, { | |
[K in keyof T]: NullUnion<T[K]> extends T[K] ? K : never; | |
}[keyof T]>> & Pick<T, { | |
[K in keyof T]: NullUnion<T[K]> extends T[K] ? never : K; | |
}[keyof T]>; | |
/*************************************/ | |
type Test = NullableToOptional<{ | |
propA: string | null; | |
propB: number | null; | |
required: boolean; | |
}>; | |
const obj: Test = { | |
required: true | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@rbardini Thank you for the inspiring blog post. Valeu mesmo!