Тип условного сопоставления Typescript с несколькими условиями

Я работаю с нормализованными данными внутри хранилища избыточности (все сложные типы - это просто идентификаторы, относящиеся к реальному объекту), и я хотел бы создать денормализованные типы, используя функцию условных сопоставленных типов машинописного текста.

Я сохраняю фактический тип объекта, на который ссылается идентификатор, как на его общий аргумент, и благодаря этому я смог правильно создать денормализованный тип, если используются только атрибуты идентификатора не массива.

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>[]

Теперь мне нужно выяснить, как добавить второе условие к DenormalizedHandler, чтобы он мог правильно отображать Id<U> в DenormalizedHandler<U> и Id<U>[] в DenormalizedHandler<U>[].


person Maroš Beťko    schedule 23.04.2019    source источник


Ответы (1)


Вам просто нужно добавить еще одно условие, условные типы могут вкладываться так же, как тернарные выражения:

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>[]
person Titian Cernicova-Dragomir    schedule 23.04.2019
comment
Я пробовал это в своем коде, и это не сработало, но по совершенно другой причине. После исправления другой ошибки все работает отлично. - person Maroš Beťko; 23.04.2019