Typescript: understanding union and Intersection types

Given the following:

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

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

Expression of Union type A | B is assignable to either A or B. It must have properties from A or B (or both)

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
}

But what operations does a type like A | B have?
Only these that belong to both A and B

oA.c = 1; // valid

Intersection type A & B, if it is assignable to both A and B (and therefore must have properties of both A and B).

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

Update

You ask “why does A & B in your example can take b prop? it’s not assignable to type A”

This is clearly not true.
Any type that has all properties of A can be assigned to A. Extra properties make no harm:

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

const ca0: A = aAndExtraProp;

You are probably confused by Excess Property Checks for object literals:

Object literals get special treatment and undergo excess property checking when assigning them to other variables, or passing them as arguments. If an object literal has any properties that the “target type” doesn’t have, you’ll get an error:

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

Leave a Comment