Типы - Union, Intersection

Чем в TypeScript можно заменить наследование? Как указать сразу диапазон типов? Ответы на эти вопросы вы сможете получить прочитав до конца данную главу.

Тип Объединение (Union Types)

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

ts
let v1: T1 | T2 | T3;

Переменной, которой был указан тип объединения A или B или C, может быть присвоено значение, принадлежащие к одному из трех типов.

ts
class A {
  a: number;
}
class B {
  b: string;
}
class C {
  c: boolean;
}

let identifier: A | B | C; // значение может принадлежать только одному типу (A или B или C)

Поскольку значение может принадлежать ко множеству порой несовместимых типов, компилятор, без вмешательства разработчика, то есть без конкретизации типа, определяет принадлежность значения к типу который наделен общими для всех типов признаками.

ts
class Bird {
    fly(): void {}
    
    toString(): string {
        return 'bird';
    }
}

class Fish {
    swim(): void {}

    toString(): string {
        return 'fish';
    }
}

class Insect {
    crawl(): void {}
    
    toString(): string {
        return 'insect';
    }
}

function move(animal: Bird | Fish | Insect): void {
    animal.fly(); // Error
    animal.swim(); // Error
    animal.crawl(); // Error
    
    animal.toString(); // ок, задекларировано во всех типах
}

Тип Пересечение (Intersection Type)

Пересечение (Intersection) — ещё один мощный механизм TypeScript, который позволяет рассматривать множество типов данных как единое целое. Пересечение указывается с помощью оператора амперсанда & по обе стороны от которого указываются типы данных.

ts
let v1: T1 & T2 & T3;

Переменной, которой был указан тип пересечение A и B и С должно быть присвоено значение принадлежащее к типам A и B и C одновременно. Другими словами значение должно обладать всеми обязательными признаками каждому типа определяющего пересечение.

ts
class A {
  a: number;
}
class B {
  b: string;
}
class C {
  c: boolean;
}

let name: A & B & C; // значение должно принадлежать ко всем типам одновременно