Skip to content

Commit ff4362e

Browse files
committed
refactor: improve removeUndefinedKeys typing
1 parent 04c3119 commit ff4362e

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

src/utilities/object.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)