Typescript: понимание типов объединения и пересечения - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь получить представление о типах Union и Intersection в машинописном тексте, но не могу понять этот случай: Playground Link

interface A {
    a: number;
}

interface B{
    b: boolean;
}



type UnionCombinedType = A | B;
type IntersectionType = A & B;

const obj: UnionCombinedType = {
    a: 6,
    b: true,
}

const obj2: IntersectionType = {
    a: 6,
    b: true,
}

Почему мне разрешено поставить оба значения в типе пересечения? Пересечение между двумя интерфейсами пусто. Если я читаю & как AND, тогда мне становится понятно, почему он позволяет мне добавлять оба реквизита, но тогда я должен прочитать ключевое слово | как OR, и я ожидаю, что оно позволит мне назначать только a или b, но не оба.

Может ли кто-нибудь дать мне некоторую интуицию об этих типах?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

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

Я думаю, вы представляете его как оператор набора на полях, а не на множестве операторов наборов каждого типа.

//////////////////////////

Это математическая терминология: «тип» - это набор всех возможных значений, например, boolean = {true, false} ;. Теперь объединение типов T и U - это множество, состоящее из значений в T или в U (т. Е. T объединено с U); аналогично пересечению значений как в T, так и в U (т.е. их общей части).

Элемент доступен, если он находится на всех возможных значениях. Для объединения значение типа T | U может быть T или U. Мы не знаем, какие допустимы только общие атрибуты. Как видите, операция над типом подразумевает другую, но дополнительную операцию над членами. Это следствие де Моргана 1 aws.

https://www.reddit.com/r/typescript/comments/9qduq3/why_is_type_intersection_called_like_that_its/

1 голос
/ 22 апреля 2020

С учетом следующего:

interface A {
    a: number;
    c: number;
}

interface B{
    b: boolean;
    c: number;
}

Выражение типа объединения A | B присваивается либо A, либо B. Он должен иметь свойства A или B (или обоих)

const oA: A | B = {
    a: 6,
    c: 6
}

const oB: A | B = {
    b: true,
    c: 6
}

const oC: A | B = {
    a: 6,
    b: true
    c: 6
}

Но какие операции имеет тип, подобный A | B? Только те, которые принадлежат как A, так и B

oA.c = 1; // valid

Тип пересечения A & B, если он назначается как A, так и B (и, следовательно, должен иметь свойства как A, так и B).

const obj: A & B = {
    a: 6,
    b: true
}

Обновление

Вы спрашиваете "почему A & B в вашем примере может брать b prop? Его нельзя назначить типу A"

Это явно не правда. Любой тип, который имеет все свойства A, может быть назначен A. Дополнительные свойства не причиняют вреда:

const aAndExtraProp = {
  a: 6,
  d: 6
};

const ca0: A = aAndExtraProp;

Возможно, вас смущают Проверка избыточного свойства для литералов объекта:

Литералы объектов получают специальную обработку и при go проверяются лишние свойства при назначении их другим переменным или передаче их в качестве аргументов. Если у литерала объекта есть какие-либо свойства, которых нет у «целевого типа», вы получите ошибку:

const ca1: A = {
  a: 6,
  d: 6 //ERROR
};
...