将所有 null 实例转换为 Typescript 中未定义的通用方法

Gra*_*ams 6 null undefined typescript reactjs

我想编写一个函数,将任何为空的对象的属性的所有实例转换为未定义。我的许多对象都有嵌套对象作为属性或值/对象数组。

解决问题时,我的第一个想法是使用泛型尝试使用泛型类型捕获每个属性的类型,然后根据需要将该属性的值从 null 转换为 undefined。

我希望编写一个足够通用的函数,可以在我的代码库中的任何不同类型和大小的对象上工作。

我一直无法找到一种简单的方法来拥有未知数量的泛型类型,所以我的下一个想法是我必须在任何地方使用 any 类型。有没有解决的办法?

我也喜欢关于方法/算法本身的一些建议。我的想法是我可能需要递归检查每个属性以查看它本身是否是具有子属性的对象,并且我还需要迭代发现的任何可能具有空值的数组,或者有一个对象这也需要递归检查。

我需要解决/回答的问题/问题:

  1. 我应该使用泛型还是任何?
  2. 如果我使用泛型,有没有办法在发现新类型时动态分配新的泛型类型?
  3. 打字稿是否有更简单的方法来递归解析对象?

我目前的方法是这样的:

inputObjectKeys.map(key, index) =>

然后有一个函数将 null 转换为 undefined,忽略非对象类型,如果它是一个对象则递归。

我假设我想使用广度优先搜索或深度优先搜索(我倾向于使用广度优先搜索来完成此特定任务)。我假设因为我需要访问每个节点,所以我可能会因为内存使用而更好地使用 DFS。

ysf*_*ran 16

接受的答案实际上并没有回答问题,因为它被要求提供通用的方式。

这是一个类似的并且也会正确转换返回类型:

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: /sf/answers/3602063671/
  if (obj.constructor.name === "Object") {
    for (let key in obj) {
      obj[key] = nullsToUndefined(obj[key]) as any;
    }
  }
  return obj as any;
}
Run Code Online (Sandbox Code Playgroud)

学分归功于这位天才的打字:https://github.com/apollographql/apollo-client/issues/2412#issuecomment-755449680


and*_*ewh 7

接受的答案不是类型安全的。

这个答案很接近,但不处理null嵌套数组内部。

这将替换null嵌套undefined对象数组中的:

type RecursivelyReplaceNullWithUndefined<T> = T extends null
  ? undefined
  : T extends (infer U)[]
  ? RecursivelyReplaceNullWithUndefined<U>[]
  : T extends Record<string, unknown>
  ? { [K in keyof T]: RecursivelyReplaceNullWithUndefined<T[K]> }
  : T;

export function nullsToUndefined<T>(
  obj: T,
): RecursivelyReplaceNullWithUndefined<T> {
  if (obj === null || obj === undefined) {
    return undefined as any;
  }

  if ((obj as any).constructor.name === 'Object' || Array.isArray(obj)) {
    for (const key in obj) {
      obj[key] = nullsToUndefined(obj[key]) as any;
    }
  }
  return obj as any;
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*n S 5

聚会有点晚了,但我认为格兰特的回答可以简化一点。这个怎么样:

function removeNulls(obj: any): any {
    if (obj === null) {
        return undefined;
    }
    if (typeof obj === 'object') {
        for (let key in obj) {
            obj[key] = removeNulls(obj[key]);
        }
    }
    return obj;
}
Run Code Online (Sandbox Code Playgroud)

  • 答案明确要求采用通用方法,但这不是通用的。 (7认同)
  • 这怎么不通用呢?从某种意义上说它不使用泛型?这个问题明确指出:_我想编写一个函数,将任何为空的对象的属性的所有实例转换为未定义。_并且_我希望编写一个足够通用的函数,可以跨任何不同类型工作,并且我在代码库中拥有的大小对象。_这两个问题都可以通过答案解决。 (3认同)