microsoft / TypeScript-Handbook

Deprecated, please use the TypeScript-Website repo instead
https://github.com/microsoft/TypeScript-Website
Apache License 2.0
4.88k stars 1.13k forks source link

Exhaustiveness checking current state #1304

Open igoradamenko opened 4 years ago

igoradamenko commented 4 years ago

Hey there!

I'm reading Handbook's “Advanced types” chapter and there's a section describing exhaustiveness checking which says (as I understand it) that this code shouldn't warn us at all about missed case in area:

interface Square {
    kind: "square";
    size: number;
}

interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}

interface Circle {
    kind: "circle";
    radius: number;
}

interface Triangle {
    kind: "triangle";
    a: number;
    b: number;
    c: number;
}

type Shape = Square | Rectangle | Circle | Triangle;

function area(s: Shape) {
    switch (s.kind) {
        case "square": return s.size * s.size;
        case "rectangle": return s.height * s.width;
        case "circle": return Math.PI * s.radius ** 2;
    }
}

But it does. As I see it works because of the noImplicitReturns flag which emits:

Not all code paths return a value. (7030)

And it disappears when we change the code into this:

function area(s: Shape) {
    switch (s.kind) {
        case "square": return s.size * s.size;
        case "rectangle": return s.height * s.width;
        case "circle": return Math.PI * s.radius ** 2;
        case "triangle": return 0; // let's pretend here's Heron's formula
    }

So I guess that the example should be a bit more complicated to describe the problem well.