I am wanting to write a function that converts all instances of a property of any object that is null to undefined. Many of my objects have nested objects as properties or arrays of values/objects.
My first thought when approaching the problem is to use generics to attempt to catch the type of each of the properties with a generic type and then to convert the value of that property from null to undefined as needed.
I am hoping to write a function that is generic enough to work across any of the different types and sized objects I have across my code code base.
I haven't been able to find an easy way to have an unknown number of generic types, so my next thought is that I'll have to use the any type everywhere. Is there a way around this?
I'd also love some advice on the approach/algorithm itself as well. My thought is that I'll probably need to recursively check each property to see if it itself is an object with sub properties, and I'll also need to iterate any arrays found that might have a null value as well, or have an object that will need to be recursively checked as well.
The problems/questions I need to solve/answer:
My current approach is something like:
inputObjectKeys.map(key, index) =>
then have a function that converts null to undefined, ignores non object types, and recurses if its an object.
I'm assuming I'd want to use a Breadth First Search or Depth First Search (I'm leaning towards Breadth First Search for this particular task). I'm assuming since i need to visit every node i might be better off with DFS simply because of the memory usage.
The accepted answer is actually not answering the question since it was asked for a generic way.
Here is one that is similar and will also cast the return type properly:
type RecursivelyReplaceNullWithUndefined<T> = T extends null
? undefined
: T extends Date
? T
: {
[K in keyof T]: T[K] extends (infer U)[]
? RecursivelyReplaceNullWithUndefined<U>[]
: RecursivelyReplaceNullWithUndefined<T[K]>;
};
export function nullsToUndefined<T>(obj: T): RecursivelyReplaceNullWithUndefined<T> {
if (obj === null) {
return undefined as any;
}
// object check based on: https://stackoverflow.com/a/51458052/6489012
if (obj.constructor.name === "Object") {
for (let key in obj) {
obj[key] = nullsToUndefined(obj[key]) as any;
}
}
return obj as any;
}
Credits go to the typings of this genius: https://github.com/apollographql/apollo-client/issues/2412#issuecomment-755449680