打字稿深省略点符号
Typescript deep omit with dot notation
由于 TypeScript 现在支持模板字面量类型,是否可以使用类似下面的内容?
interface Data {
a: number;
b: {
c: number;
d: number;
}
}
type OmitDeep<T, K> = ...
type WithoutC = OmitDeep<Data, 'b.c'>
其中 WithoutC
将被推断为:
interface WithoutC {
a: number;
b: {
d: number
}
}
您可以使用此类型将点路径映射到数组路径:
type UnDot<T extends string> =
T extends `${infer A}.${infer B}` ? [A, B] : ''
type ProperyArray = UnDot<'a.b'>; // ["a", "b"]
然后使用此答案删除嵌套属性:
编辑任意数量的嵌套级别:
type UnDot<T extends string> =
T extends `${infer A}.${infer B}`
? [A, ...UnDot<B>]
: [T];
除了 Roberto 的精彩回答外,完整的解决方案如下所示:
type Tail<T extends any[]> = ((...t: T) => void) extends ((
h: any,
...r: infer R
) => void)
? R
: never;
type DeepOmit<T, Path extends string[]> = T extends object ?
Path['length'] extends 1 ? Omit<T, Path[0]> : {
[K in keyof T]: K extends Path[0] ? DeepOmit<T[K], Tail<Path>> : T[K];
} : T;
type UnDot<T extends string> =
T extends `${infer A}.${infer B}`
? [A, ...UnDot<B>]
: [T];
type Nested = {
a: number;
b: {
c: number;
d: number;
}
};
type Omitted = DeepOmit<Nested, UnDot<'b.c'>>
const foo: Omitted = {a: 1, b: { c: 1, d: 2 } }; // error
~~~~
由于 TypeScript 现在支持模板字面量类型,是否可以使用类似下面的内容?
interface Data {
a: number;
b: {
c: number;
d: number;
}
}
type OmitDeep<T, K> = ...
type WithoutC = OmitDeep<Data, 'b.c'>
其中 WithoutC
将被推断为:
interface WithoutC {
a: number;
b: {
d: number
}
}
您可以使用此类型将点路径映射到数组路径:
type UnDot<T extends string> =
T extends `${infer A}.${infer B}` ? [A, B] : ''
type ProperyArray = UnDot<'a.b'>; // ["a", "b"]
然后使用此答案删除嵌套属性:
编辑任意数量的嵌套级别:
type UnDot<T extends string> =
T extends `${infer A}.${infer B}`
? [A, ...UnDot<B>]
: [T];
除了 Roberto 的精彩回答外,完整的解决方案如下所示:
type Tail<T extends any[]> = ((...t: T) => void) extends ((
h: any,
...r: infer R
) => void)
? R
: never;
type DeepOmit<T, Path extends string[]> = T extends object ?
Path['length'] extends 1 ? Omit<T, Path[0]> : {
[K in keyof T]: K extends Path[0] ? DeepOmit<T[K], Tail<Path>> : T[K];
} : T;
type UnDot<T extends string> =
T extends `${infer A}.${infer B}`
? [A, ...UnDot<B>]
: [T];
type Nested = {
a: number;
b: {
c: number;
d: number;
}
};
type Omitted = DeepOmit<Nested, UnDot<'b.c'>>
const foo: Omitted = {a: 1, b: { c: 1, d: 2 } }; // error
~~~~