Search code examples
typescripttypescript-genericstype-narrowing

Typing a function to replace objects' null values with undefined


How would you type a function that accepts any object and returns the same object just with all the null values set to undefined. It should work in strict mode enabled.

The function implementation looks like this

export const undefineNullValues = (obj) => {
  return Object.fromEntries(
    Object.entries(obj ?? {}).map(([key, value]) => {
      return value === null ? [key, undefined] : [key, value];
    })
  );
};

I have tried the following:

type Return<T> = {
  [key in keyof T]: T[keyof T] extends null ? undefined : T[keyof T];
};

export const undefineNullValues = <T extends Record<string, any>>(
  obj: T
): Return<T> => {
  return Object.fromEntries(
    Object.entries(obj ?? {}).map(([key, value]) => {
      return value === null ? [key, undefined] : [key, value];
    })
  );
};

But I get the error

Type '{ [k: string]: any; }' is not assignable to type 'Return<T>.

Solution

  • You can try force with as.

    type Return<T> = {
      [key in keyof T]: T[keyof T] extends null ? undefined : T[keyof T];
    };
    
    export const undefineNullValues = <T extends Record<string, unknown>>(
      obj: T,
    ): Return<T> => {
      return Object.fromEntries(
        Object.entries(obj ?? {}).map(([key, a]) => [key, a ?? undefined]),
      ) as Return<T>;
    };