You could do something like this
const isPlainObject = (value: unknown): value is PlainObj =>
typeof value === "object" && value !== null && !Array.isArray(value);
export type DeNullify<T> = T extends null
? undefined
: T extends { [key: string]: any }
? { [K in keyof T]: DeNullify<T[K]> }
: T;
export const deNullify = <T>(src: T): DeNullify<T> => {
if (src === null) return undefined as DeNullify<T>;
if (isPlainObject(src)) {
const obj = Object.create(null);
for (const [key, value] of Object.entries(src)) {
obj[key] = deNullify(value);
}
return obj;
}
return src;
};
const obj = deNullify({ a: 1, b: 2, c: undefined, d: null }) // { a: 1, b: 2, c: undefined, d: undefined }
Update: I ended up publishing it to NPM. You can install it npm install dnull