// https://gist.github.com/tkrotoff/a6baf96eb6b61b445a9142e5555511a0 import type { Primitive } from "type-fest"; type NullToUndefined = T extends null ? undefined : T extends Primitive | Function | Date | RegExp ? T : T extends Array ? Array> : T extends Map ? Map> : T extends Set ? Set> : T extends object ? { [K in keyof T]: NullToUndefined } : unknown; type UndefinedToNull = T extends undefined ? null : T extends Primitive | Function | Date | RegExp ? T : T extends Array ? Array> : T extends Map ? Map> : T extends Set ? Set> : T extends object ? { [K in keyof T]: UndefinedToNull } : unknown; function _nullToUndefined(obj: T): NullToUndefined { if (obj === null) { return undefined as any; } if (typeof obj === "object") { if (obj instanceof Map) { obj.forEach((value, key) => obj.set(key, _nullToUndefined(value))); } else { for (const key in obj) { obj[key] = _nullToUndefined(obj[key]) as any; } } } return obj as any; } function _undefinedToNull(obj: T): UndefinedToNull { if (obj === undefined) { return null as any; } if (typeof obj === "object") { if (obj instanceof Map) { obj.forEach((value, key) => obj.set(key, _undefinedToNull(value))); } else { for (const key in obj) { obj[key] = _undefinedToNull(obj[key]) as any; } } } return obj as any; } /** * Recursively converts all undefined values to null. * * @param obj object to convert * @returns a copy of the object with all its undefined values converted to null */ export function undefinedToNull(obj: T) { return _undefinedToNull(structuredClone(obj)); }