具有多个条件的 Typescript 条件映射类型

Mar*_*ťko 2 typescript typescript-generics

我正在 redux 存储中处理规范化数据(所有复杂类型只是引用真实对象的 id),并且我想使用 typescript 的条件映射类型功能创建非规范化类型。

我保留 id 所引用的对象的实际类型,因为它是通用参数,并且如果仅使用非数组 id 属性,我就能够正确创建非规范化类型。

type Id<T extends HandlerBase<any>> = string & { __type: T };

class HandlerBase<T extends HandlerBase<T>> {};

class HandlerA extends HandlerBase<HandlerA> {
    str: string;
    b: Id<HandlerB>;
    bArr: Id<HandlerB>[];
};

class HandlerB extends HandlerBase<HandlerA> {};

type DenormalizedHandler<T> = {
    [P in keyof T]: T[P] extends Id<infer U> ? DenormalizedHandler<U> : T[P];
}

const handler: DenormalizedHandler<HandlerA> = undefined;
handler.str; // Is string
handler.b; // Is DenormalizedHandler<HandlerB>
handler.bArr; // Should be DenormalizedHandler<HandlerB>[]
Run Code Online (Sandbox Code Playgroud)

现在我需要弄清楚如何添加第二个条件,以便DenormalizedHandler它可以正确映射Id<U>DenormalizedHandler<U>和。Id<U>[]DenormalizedHandler<U>[]

Tit*_*mir 5

您只需要添加另一个条件,条件类型可以像三元表达式一样嵌套:

type Id<T extends HandlerBase<any>> = string & { __type: T };

class HandlerBase<T extends HandlerBase<T>> {};

class HandlerA extends HandlerBase<HandlerA> {
    str: string;
    b: Id<HandlerB>;
    bArr: Id<HandlerB>[];
};

class HandlerB extends HandlerBase<HandlerA> {};

type DenormalizedHandler<T> = {
    [P in keyof T]: 
        T[P] extends Id<infer U> ? DenormalizedHandler<U> : 
        T[P] extends Array<Id<infer U>> ? Array<DenormalizedHandler<U>> : 
        T[P];
}

const handler: DenormalizedHandler<HandlerA> = undefined;
handler.str; // Is string
handler.b; // Is DenormalizedHandler<HandlerB>
handler.bArr; // Is DenormalizedHandler<HandlerB>[]
Run Code Online (Sandbox Code Playgroud)