Поменяйте местами один тип TypeScript с другим внутри объекта - PullRequest
0 голосов
/ 21 января 2020

У меня есть следующие типы:

type Target = number | undefined;

type MyObject = {
    some: string;
    properties: string;
    id: Target;
}

Я хочу предложить универсальный c способ заменить Target на number, например:

type MyObjectTransformed = TargetToNumber<MyObject>;

/**
 * MyObjectTransformed is now:
 * 
 * {
 *     some: string;
 *     properties: string;
 *     id: number;
 * }
 */

Легко, если вы знаете, что Target всегда находится в поле id, мне не нужна помощь с этим.

Но что, если Target может быть где угодно? Как это должно работать:

TargetToNumber<{
    some: string;
    other: Target;
    properties: string;
}>

И что еще хуже ... оно также должно работать, когда оно вложено! Как это все равно следует заменить Target на number:

TargetToNumber<{
    some: string;
    properties: string;
    nested: {
        arbitrarily: {
            deep: Target;
        };
    };
}>

Если вам интересно, почему я хочу сделать такую ​​странную вещь, , поэтому я спрашиваю .

1 Ответ

3 голосов
/ 21 января 2020

Использование условного типа: если произвольный тип T равен A или подтип 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;

Если вы хотите заменить только A и оставить только подтипы A (например, never всегда является подтипом ...), вы можете заменить T extends A с [A, T] extends [T, A] для проверки того, что они одного типа.

Playground Link

...