TypeScript - 删除具有特定类型的所有属性
TypeScript - remove all properties with particular type
我有一个 type
,用于将 T
中存在的键投影到 U
中存在的通用键及其类型:
type IntersectByCommonKey<T, U, V = any> = {
[K in keyof U]: K extends keyof T ?
T[K] extends V ?
U[K]
: T[K] extends object ?
IntersectByCommonKey<T[K], U[K], V>
: T[K] extends object | undefined ?
IntersectByCommonKey<T[K], U[K], V> | undefined
: never
: never
};
IntersectByCommonKey Playground Link
对于 U
中的每个键 K
,如果 T
具有相同的键 K
,并且如果 K
处的类型 extends V
,包括该键的形状,否则 never
.
对于 IntersectByCommonKey
返回的类型,我想删除每个具有 never
类型的键,这意味着它也必须处理嵌套的 Record
形状。
删除顶级密钥非常容易:
type ExcludeKeysWithTypeOf<T, V> = {
[K in keyof T]: Exclude<T[K], undefined> extends V ? never : K
}[keyof T]
type Without<T, V> = Pick<T, ExcludeKeysWithTypeOf<T, V>>;
ExcludeKeysWithTypeOf Playground Link
但是,我正在努力为嵌套的 Record
实现相同的结果,有没有一种方法可以递归删除类型为 never
的键?
我们需要进行递归调用以进入嵌套记录类型。
这里有一个示例解决方案:
type Without<T, V, WithNevers = {
[K in keyof T]: Exclude<T[K], undefined> extends V ? never
: (T[K] extends Record<string, unknown> ? Without<T[K], V> : T[K])
}> = Pick<WithNevers, {
[K in keyof WithNevers]: WithNevers[K] extends never ? never : K
}[keyof WithNevers]>
核心思想是当我们的T[K]
将拥有Record类型时,它会递归地再次调用自身(Without
类型级函数)。整个类型将减少到所需的形式,其中每个嵌套对象都将删除我们想要的键。
整个代码片段 - the playground
注意: 我将 WithNevers
的计算移到类型的参数列表中,以实现更好的可读性。我们也可以将其定义为单独的类型。
我有一个 type
,用于将 T
中存在的键投影到 U
中存在的通用键及其类型:
type IntersectByCommonKey<T, U, V = any> = {
[K in keyof U]: K extends keyof T ?
T[K] extends V ?
U[K]
: T[K] extends object ?
IntersectByCommonKey<T[K], U[K], V>
: T[K] extends object | undefined ?
IntersectByCommonKey<T[K], U[K], V> | undefined
: never
: never
};
IntersectByCommonKey Playground Link
对于 U
中的每个键 K
,如果 T
具有相同的键 K
,并且如果 K
处的类型 extends V
,包括该键的形状,否则 never
.
对于 IntersectByCommonKey
返回的类型,我想删除每个具有 never
类型的键,这意味着它也必须处理嵌套的 Record
形状。
删除顶级密钥非常容易:
type ExcludeKeysWithTypeOf<T, V> = {
[K in keyof T]: Exclude<T[K], undefined> extends V ? never : K
}[keyof T]
type Without<T, V> = Pick<T, ExcludeKeysWithTypeOf<T, V>>;
ExcludeKeysWithTypeOf Playground Link
但是,我正在努力为嵌套的 Record
实现相同的结果,有没有一种方法可以递归删除类型为 never
的键?
我们需要进行递归调用以进入嵌套记录类型。 这里有一个示例解决方案:
type Without<T, V, WithNevers = {
[K in keyof T]: Exclude<T[K], undefined> extends V ? never
: (T[K] extends Record<string, unknown> ? Without<T[K], V> : T[K])
}> = Pick<WithNevers, {
[K in keyof WithNevers]: WithNevers[K] extends never ? never : K
}[keyof WithNevers]>
核心思想是当我们的T[K]
将拥有Record类型时,它会递归地再次调用自身(Without
类型级函数)。整个类型将减少到所需的形式,其中每个嵌套对象都将删除我们想要的键。
整个代码片段 - the playground
注意: 我将 WithNevers
的计算移到类型的参数列表中,以实现更好的可读性。我们也可以将其定义为单独的类型。