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"
TS Playground
Is there any difference between Extract and &?
The intersection operator & is used to extend types (make a more specific type that is a subtype of each of the operands).
In contrast, the documentation says this about the Extract<Type, Union> utility:
Constructs a type by extracting from
Typeall union members that are assignable toUnion.
In the case of literals (for example, number and string literals), these are equivalent: unions of literal types with less membership are more specific than unions with greater membership, so it simply works like the center, overlapping area of a Venn diagram in both cases:

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.
TS Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With