在对象内将一种 TypeScript 类型与另一种类型交换

dum*_*ter 1 typescript typescript-generics

我有以下类型:

type Target = number | undefined;

type MyObject = {
    some: string;
    properties: string;
    id: Target;
}
Run Code Online (Sandbox Code Playgroud)

我想想出一种通用的方法来替换Targetnumber例如:

type MyObjectTransformed = TargetToNumber<MyObject>;

/**
 * MyObjectTransformed is now:
 * 
 * {
 *     some: string;
 *     properties: string;
 *     id: number;
 * }
 */
Run Code Online (Sandbox Code Playgroud)

如果你知道Target他总是在id现场,那就很容易了,我不需要这方面的帮助。

但如果Target可以在任何地方呢?像这样也应该有效:

TargetToNumber<{
    some: string;
    other: Target;
    properties: string;
}>
Run Code Online (Sandbox Code Playgroud)

更糟糕的是......它还需要在嵌套时工作!像这样仍然应该替换Targetnumber

TargetToNumber<{
    some: string;
    properties: string;
    nested: {
        arbitrarily: {
            deep: Target;
        };
    };
}>
Run Code Online (Sandbox Code Playgroud)

如果你好奇我为什么要做这么奇怪的事情,这就是我问的原因

kay*_*ya3 5

使用条件类型:如果任意类型TA或其子类型A,我们将其替换为B,否则,如果它是对象类型,我们将递归映射属性,否则我们将类型保留为T

type TargetToNumber<T> = SubstituteType<T, Target, number>;

type SubstituteType<T, A, B> =
    T extends A
    ? B
    : T extends {}
    ? { [K in keyof T]: SubstituteType<T[K], A, B> }
    : T;
Run Code Online (Sandbox Code Playgroud)

如果您只想精确替换A并保留子类型A(例如never始终是子类型...),您可以替换T extends A[A, T] extends [T, A]来测试它们是否是同一类型。

游乐场链接