A shared literal field lets TypeScript narrow a union to the matching object shape.

Discriminated Unions

discriminated.ts
type Circle = {
    kind: "circle";
    radius: number;
};

type Square = {
    kind: "square";
    side: number;
};

type Shape = Circle | Square;

function area(shape: Shape): number {
    if (shape.kind === "circle") {
        return Math.PI * shape.radius * shape.radius;
    }
    return shape.side * shape.side;
}

const shapeKind: "circle" | "square" = ;
const shape: Shape = shapeKind === "circle"
    ? { kind: "circle", radius: 3 }
    : { kind: "square", side: 4 };
const result: number = area(shape);

console.log(`${shape.kind} area=${result.toFixed(2)}`);
type Circle = {
    kind: "circle";
    radius: number;
};

type Square = {
    kind: "square";
    side: number;
};

type Shape = Circle | Square;

function area(shape: Shape): number {
    if (shape.kind === "circle") {
        return Math.PI * shape.radius * shape.radius;
    }
    return shape.side * shape.side;
}

const shapeKind: "circle" | "square" = ;
const shape: Shape = shapeKind === "circle"
    ? { kind: "circle", radius: 3 }
    : { kind: "square", side: 4 };
const result: number = area(shape);

console.log(`${shape.kind} area=${result.toFixed(2)}`);
discriminated union A discriminated union uses one field, often named `kind`, to tell each case apart.