假设您想“一次性”进行更换并且not作为“链”(意味着你不打算替换X
with Y
and then代替Y
with Z
),那么你可以重写DeepReplace
建立工会M
对应于的映射元组[Condition1, Replacement1] | [Condition2, Replacement2] | ...
。所以你的老DeepReplace<T, C, R>
将会DeepReplace<T, [C, R]>
。定义如下:
type DeepReplace<T, M extends [any, any]> = {
[P in keyof T]: T[P] extends M[0]
? Replacement<M, T[P]>
: T[P] extends object
? DeepReplace<T[P], M>
: T[P];
}
where Replacement<M, T>
查找映射元组M
where T
可分配给条件并返回相应的替换,定义如下:
type Replacement<M extends [any, any], T> =
M extends any ? [T] extends [M[0]] ? M[1] : never : never;
让我们看看它是否适用于我将在这里弥补的某些类型。鉴于以下情况:
interface DateLike {
v: Date;
}
interface StringLike {
v: string;
}
interface NumberLike {
v: number;
}
interface Original {
a: {
dat: DateLike;
str: StringLike;
num: NumberLike;
boo: boolean
},
b: {
arr: NumberLike[]
},
c: StringLike,
d: number
}
让我们替换...Like
types:
type Replaced = DeepReplace<Original,
[DateLike, Date] | [StringLike, string] | [NumberLike, number]
>
/* equivalent to
type Replaced = {
a: {
dat: Date;
str: string;
num: number;
boo: boolean;
};
b: {
arr: number[];
};
c: string;
d: number;
}
*/
这样就可以了。
请注意,调用新DeepReplace<T, [C, R]>
这可能与原始情况具有相同的边缘情况DeepReplace<T, C, R>
有。例如,工会如{a: string | DateLike}
不会被映射。我会认为对这些的任何调整都超出了问题的范围。
好的,希望有帮助;祝你好运!
Playground 代码链接 https://www.typescriptlang.org/play/#code/C4TwDgpgBAIhFgEoIDYEMDGEA8AVANFALJQQAewEAdgCYDOUA2mlSISyALoB8UAvFADeAWABQUCUwAKUAJZUoAawggA9gDMouTgC4tjKZ1IVq9YowAMnMZKgB+KMjDosAW2rBsRQrgM8bknq+hsaUtAyqAEYAVhAYwAESDnAITi44wZyERNyJUEF+ANxiAL5iYqCQjqiYEO5UniTkYWbMrOysWVq8fHlNJuFQHPZM2qGmDIxElpxGDtMAjEZ6VBAAbhAATvlQqxubxaLlovKUm+q1sGiUADKyykJ5a3ow1xCHZScNWxdYUADKwE28gA5ncHiJxJJnlA6EDQR8xKcfpcAHIAV1ckS24OgkNsMKomOxB1Kx2R50uAHlgSD5GgUI8oRI0Hp8bZJDRri83rjDhzJHDNnpAcCqGD7u88rYia49BisTjJfyBVBIqpVHp1aoUBAWHkSvg8pE2dLJGhNsKoAqSbjGNZmVBDXkMCL4eLcUbHTQVsStmSjqJKtA0rUaPxYPAkDUsNgabI6VQGYRGK9bpLCGmIEYAD5MUWgz2w90g3NMG1K5SEWUk-yiAD0ACpSABHdGyNYMjxQYCqCrgEMxiDhgTslmmx22LnAHmUFUCoV6IUIs0SWW+xWkyeSbVajW6ljzp1Hk1M1VDS0bkn2o8lI+u4tikFHn27P1bz6N+tiIA