It’s a union where all types has the same member of literal type, and can be used to narrow down exact type of the object.

Example:

interface Square {
    kind: "square";
    size: number;
}
 
interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}
 
type Shape = Square | Rectangle;
 
function area(s: Shape) {
    if (s.kind === "square") {
        // Now TypeScript *knows* that `s` must be a square ;)
        // So you can use its members safely :)
        return s.size * s.size;
    }
    else {
        // Wasn't a square? So TypeScript will figure out that it must be a Rectangle ;)
        // So you can use its members safely :)
        return s.width * s.height;
    }
}

See also