Last active
July 12, 2023 20:11
-
-
Save mrclay/a797ad7e4989e416412b3aaafddbbc2f to your computer and use it in GitHub Desktop.
Destructure objects so that defaults can be given for nulls, too.
This file contains hidden or 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 OmitNull<T> = T extends null ? Exclude<T, null> | undefined : T; | |
type OmitNullProps<T extends object> = { [Key in keyof T]: OmitNull<T[Key]> }; | |
/** | |
* Allow destructuring an object, turning any null properties into undefined so | |
* a default can be given. If the given object may be null/undefined, then every | |
* property may be undefined. | |
* | |
* Useful for assigning defaults for properties that may be null. In a usual destructuring | |
* assignment, nulls are passed through so you can't provide a default for that case: | |
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#default_value | |
*/ | |
export function withoutNulls<T extends object>(value: T): OmitNullProps<T>; | |
export function withoutNulls<T extends object>( | |
value: T | null | undefined, | |
): Partial<OmitNullProps<T>>; | |
export function withoutNulls(value: unknown) { | |
return Object.fromEntries( | |
Object.entries(value || {}).filter(kv => kv[1] !== null), | |
); | |
} | |
// DEMO | |
const foo = { | |
string1: 'String', | |
string2: 'String', | |
maybeNull1: 'maybeNull' as string | null, | |
maybeNull2: 'maybeNull' as string | null, | |
}; | |
// ✓ Possibilities of null are replaced by undefined. | |
const { | |
string1, | |
maybeNull1, | |
} = withoutNulls(foo); | |
// ✓ If the given object may be null/undefined then everything might be undefined. | |
const { | |
string2, | |
maybeNull2, | |
// ✓ Unrecogniged keys flagged as errors. | |
unrecognized, | |
} = withoutNulls(null as typeof foo | null); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment