J.Wolfe
J.Wolfe

Reputation: 798

Why is Typescript unable to infer the correct type based off an enum switch statement?

enum Test {
  one,
  two,
}

const play = (n: Test) => {
  switch (n) {
    case Test.one:
      return 'hello';
    case Test.two:
      return {};

    default:
      exhaustive(n);
      throw new Error('hi');
  }
};

const b = play(Test.one);

//
console.log(b);

Can someone help me understand why Typescript can't infer that the return type of play(Test.one) is a string instead of an object? Also, if there's something I can do to make it work, I would love to know that as well.

Typescript 3.9.4

Hovering over the typeof b yields: wrong inferred type

Upvotes: 3

Views: 621

Answers (2)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250106

Typescript will not try to infer anything like this accurately (basically infer overloads based on the switch statements). The best you can hope for from TS inference is a union of all possible return types. In your case you get the return type as {} because most types are compatible with {}, even string so the union {} | string simplifies to {}.

Your only solution here is to be explicit about the return types using multiple overloads (although you will need a function declaration, overloads can't be defined on a function expression):

function play(n: Test.one): "hello"
function play(n: Test.two): {}
function play(n: Test) {
    switch (n) {
        case Test.one:
            return 'hello';
        case Test.two:
            return {};

        default:
            exhaustive(n);
            throw new Error('hi');
    }
};

const b = play(Test.one); // "hello"

Playground Link

Note: Your implementation will not be checked against the overloads, so it's up to you to ensure that implementation and overloads agree.

Upvotes: 1

Sándor Jankovics
Sándor Jankovics

Reputation: 898

The reason is that every return value has a different type one returns a string one returns an object and one an error. This way linter will choose the base class which is object

Upvotes: 1

Related Questions