Last active
May 21, 2021 19:44
-
-
Save nvitaterna/bc198119379b18f7df0d6f9cc6c100f9 to your computer and use it in GitHub Desktop.
Typesafe function to convert all possible null values to undefined recursively
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
type UndefinedProperties<T> = { | |
[P in keyof T]-?: undefined extends T[P] ? P : never; | |
}[keyof T]; | |
type ToOptional<T> = Partial<Pick<T, UndefinedProperties<T>>> & | |
Pick<T, Exclude<keyof T, UndefinedProperties<T>>>; | |
type NeverFallback<T> = [T] extends [never] ? undefined : T; | |
export type ExcludeNull<O extends unknown> = O extends Record<string, unknown> | |
? ToOptional< | |
{ | |
[K in keyof O]: O[K] extends Record<string, unknown> | |
? ExcludeNull<O[K]> | |
: O[K] extends Array<unknown> | |
? Array<ExcludeNull<O[K][keyof O[K]]>> | |
: NeverFallback<Exclude<O[K], null>>; | |
} | |
> | |
: O extends Array<unknown> | |
? Array<ExcludeNull<O[keyof O]>> | |
: NeverFallback<Exclude<O, null>>; | |
export function nullToUndefined<T = unknown>(input: T): ExcludeNull<T>; | |
export function nullToUndefined<T = unknown>(input: T) { | |
if (input === null) { | |
return undefined; | |
} | |
if (Array.isArray(input)) { | |
return input.map((value) => nullToUndefined(value)); | |
} | |
if (typeof input === 'object') { | |
const returnObj: Record<string, unknown> = {}; | |
Object.entries(input).forEach(([key, value]) => { | |
returnObj[key] = nullToUndefined(value); | |
}); | |
return returnObj as ExcludeNull<T>; | |
} | |
return input; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment