【问题标题】:Typing recursive function removing property from object键入递归函数从对象中删除属性
【发布时间】:2021-01-26 08:36:14
【问题描述】:

我有一个函数可以递归地从所有对象中删除特定属性。如果我们用 Javascript 编写它,它将是:

function removeRecursive(value) {
  if (Array.isArray(value)) {
    return value.map(removeRecursive);
  }

  if (typeof value === "object") {
    return Object.keys(value)
      .filter(key => key !== "remove")
      .reduce((acc, key) => {
        acc[key] = removeRecursive(value[key]);
        return acc;
      }, {});
  }
  return value;
};

例如:

removeRecursive({
  foo: {
    bar: 'foo.bar',
    remove: 'this'
  },
  remove: 'also-this',
  list: [{
    remove: 'this-as-well',
    baz: 'baz'
  }]
})

会导致:

{
  "foo": {
    "bar": "foo.bar"
  },
  "list": [
    {
      "baz": "baz"
    }
  ]
}

知道如何输入这个吗?似乎我应该有足够的信息能够返回一个新类型,该类型以某种方式递归返回相同的类型,而 remove 属性从任何对象类型中都省略了。

【问题讨论】:

标签: typescript typescript-generics


【解决方案1】:

我用通用的Drop 写了这个,而不仅仅是一个文字字符串"remove",但我们可以将Drop 的默认值设置为"remove"

type Removed<T, Drop = "remove"> = T extends object ? {
    [K in Exclude<keyof T, Drop>]: Removed<T[K], Drop>
} : T;

T 代表整个值。在对象的每个级别,我们只想保留不能分配给我们的Drop 通用键:Exclude&lt;keyof T, Drop&gt; 的键。要递归地应用它,该键的新值本身必须被过滤:Removed&lt;T[K], Drop&gt;T extends object ? {...} : T; 实际上不是必需的,但会导致更清晰的推断类型。

Typescript Playground Link

这将检查您的示例输入和输出。但是,将类型应用于您的函数是一团糟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    相关资源
    最近更新 更多