typescript - 使用打字稿进行深度省略
问题描述
是否可以在一个函数上保持类型覆盖,从而深度删除对象中键的所有实例?
我的功能看起来像这样。
function omitDeep<T extends object>(obj: T, key: string): TWithoutProvidedKey {
return JSON.parse(
JSON.stringify(obj),
(key: string, value: any) => key === "__typename" ? undefined : value
);
}
有什么办法可以实现TWithoutProvidedKey
吗?
解决方案
这很容易做到,您只需要使用映射类型来递归属性:
type Primitive = string | Function | number | boolean | Symbol | undefined | null
type DeepOmitHelper<T, K extends keyof T> = {
[P in K]: //extra level of indirection needed to trigger homomorhic behavior
T[P] extends infer TP ? // distribute over unions
TP extends Primitive ? TP : // leave primitives and functions alone
TP extends any[] ? DeepOmitArray<TP, K> : // Array special handling
DeepOmit<TP, K>
: never
}
type DeepOmit<T, K> = T extends Primitive ? T : DeepOmitHelper<T,Exclude<keyof T, K>>
type DeepOmitArray<T extends any[], K> = {
[P in keyof T]: DeepOmit<T[P], K>
}
type Input = {
__typename: string,
a: string,
nested: {
__typename: string,
b: string
}
nestedArray: Array<{
__typename: string,
b: string
}>
nestedTuple: [{
__typename: string,
b: string
}]
}
type InputWithoutKey = DeepOmit<Input, '__typename'>
let s: InputWithoutKey = {
a: "",
nested: {
b:""
},
nestedArray: [
{b: ""}
],
nestedTuple: [
{ b: ""},
]
}
只是一个警告,这适用于 3.4,数组和元组上映射类型的处理最近发生了变化,因此根据版本,您可能需要将数组作为特殊情况处理。
推荐阅读
- c# - XDocument.Parse(xmlstring) 空间丢失
- javascript - 如何将下一个字符串分组?
- android - 将活动中的数据传递回 recyclerview 适配器
- google-cloud-platform - 保存更多检查点 Cloud ML Engine
- python - 定义更短的等待函数
- swift - 如何在 mapKit 中绘制路线?
- vba - 我有一个独特设备列表和 4 种不同的关税来创建一个新列表,每个设备和关税有 1 行
- powershell - PowerShell - 从子数组中的列中选择单个值
- android - android在膨胀布局时崩溃
- javascript - E4x xml 空标签删除