我有一个函数可以递归地从所有对象中删除一个特定的属性。如果我们用 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
属性。
答案 0 :(得分:0)
我用泛型 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<keyof T, Drop>
的键。要递归地应用它,必须过滤该键的新值本身:Removed<T[K], Drop>
。 T extends object ? {...} : T;
实际上不是必需的,但会导致更清晰的推断类型。
这会检查您的示例输入和输出。但是,将类型应用于您的函数是一团糟。