@@ -8,6 +8,22 @@ export const isKeyInObject = <Key extends string>(
88 // eslint-disable-next-line @typescript-eslint/ban-types
99) : object is object & Record < Key , unknown > => isObject ( object ) && key in object ;
1010
11+ /**
12+ * A utility type that removes all keys with `undefined` values from an object.
13+ *
14+ * Note: Optional keys with `undefined` values are not removed.
15+ *
16+ * @example
17+ * ```ts
18+ * type Foo = { a: string; b: number | undefined; c?: boolean };
19+ * type Bar = RemoveUndefinedKeys<Foo>;
20+ * // Bar is { a: string; b: number; c?: boolean }
21+ * ```
22+ */
23+ type RemoveUndefinedKeys < T > = {
24+ [ Key in keyof T as T [ Key ] extends undefined ? never : Key ] : Exclude < T [ Key ] , undefined > ;
25+ } ;
26+
1127/**
1228 * Remove all keys with `undefined` values from an object. This function only
1329 * performs a shallow removal, i.e. it does not remove `undefined` values nested
@@ -16,6 +32,9 @@ export const isKeyInObject = <Key extends string>(
1632 * @param object The object to remove `undefined` keys from.
1733 * @returns A new object with all `undefined` keys removed.
1834 */
19- export const removeUndefinedKeys = < T extends Record < string , unknown > > ( object : T ) : T =>
35+ // eslint-disable-next-line @typescript-eslint/ban-types -- this is a utility function
36+ export const removeUndefinedKeys = < T extends object > ( object : T ) : RemoveUndefinedKeys < T > =>
2037 // eslint-disable-next-line no-restricted-syntax
21- Object . fromEntries ( Object . entries ( object ) . filter ( ( [ , value ] ) => value !== undefined ) ) as T ;
38+ Object . fromEntries (
39+ Object . entries ( object ) . filter ( ( [ , value ] ) => value !== undefined )
40+ ) as RemoveUndefinedKeys < T > ;
0 commit comments