Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exhaustiveness checking doesn't work with variables #12668

Closed
asyschikov opened this issue Dec 5, 2016 · 1 comment · Fixed by #32695
Closed

Exhaustiveness checking doesn't work with variables #12668

asyschikov opened this issue Dec 5, 2016 · 1 comment · Fixed by #32695
Labels
Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds

Comments

@asyschikov
Copy link

TypeScript Version: 2.1.1

If you have exhaustiveness checking where a result is a return from a function it works.
But if result is assigning value to a variable exhaustiveness checking basically does nothing.

Code

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

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

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

interface Triangle { kind: "triangle"; side: number; }

type Shape = Square | Rectangle | Circle | Triangle;

function area(s: Shape): number {
    let area;
    switch (s.kind) {
        case "square": area = s.size * s.size; break;
        case "rectangle": area = s.width * s.height; break;
        case "circle": area = Math.PI * s.radius * s.radius; break;
        case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break;
        //default: area = -1; break;
    }
    //Error because area is number | undefined
    return area;
}

function areaWrapped(s: Shape): number {
    let area;
    area = (() => {
        switch (s.kind) {
            case "square": return s.size * s.size;
            case "rectangle": return s.width * s.height;
            case "circle": return Math.PI * s.radius * s.radius;
            case "triangle": return Math.sqrt(3) / 4 * s.side * s.side;
        }
    })();
    return area;
}

Expected behavior:

Function area: variable aria should be number because the check is exhaustive.
Sidenotes:

  1. If I uncomment default then tsc believes that check is exhaustive.
  2. areaWrapped uses IIFE to achieve the same effect and it works.

Actual behavior:

Variable area is of type number | undefined while it can't be undefined.

@RyanCavanaugh RyanCavanaugh added In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels Dec 5, 2016
@RyanCavanaugh RyanCavanaugh added Too Complex An issue which adding support for may be too complex for the value it adds and removed In Discussion Not yet reached consensus labels Jul 29, 2019
@RyanCavanaugh
Copy link
Member

There are architectural / phase-ordering things that make this more complex than it first appears. Anyway adding a sensible default: throw new Error(); case makes the error go away, or add let! area;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants