Given the following code:
type abc = "a" | "b" | "c"
type af = "a" | "f"
type T0 = Extract<abc, af>;
// type T0 = "a"
type T2 = abc & af
// type T0 = "a"
type Num = 1 | 2 | 3;
type Bin = 0 | 1;
type IntersectionN = Num & Bin; // 1
type ExtractionN = Extract<Num, Bin>; // 1
When considering object types, the two work very differently. Consider this example:
type A = {
b: boolean;
s: string;
};
type B = {
b: boolean;
n: number;
};
type IntersectionC = A & B;
declare const ci: IntersectionC;
ci.b // boolean
ci.n // number
ci.s // string
type ExtractionC = Extract<A, B>;
declare const ce: ExtractionC;
ce // never
The intersection of the two types creates a new object with the members of each input object.
In contrast, extracting from union A
the members which are assignable to B
yields never
because A
is not assignable to B
.