Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type inference with union types - No best common type exists

Tags:

typescript

So, I am playing with type inference in TypeScript. I will provide two examples that produces the same results when invoked, however in one of them TypeScript cannot infer the type due to "No best common type".

Example with ternary operator

function foo(a: boolean) {
    return a ? 4 : true;
}

The compiler infers that foo is (a: boolean) => number | boolean which is awesome.

Example with if statement

function foo(a: boolean) {
    if (a) {
        return 4;
    } else {
        return true;
    }
}

The compiler complains about "No best common type" when trying to infer return type. It confuses me that if statements should mess with the type inference. How come?

like image 270
Peter Avatar asked Apr 07 '16 14:04

Peter


1 Answers

That error will be thrown when the return statements in a function do not have a common type. This can only happen when multiple return statements exist.

First example - One return statement

In the first example there is only one return statement that returns a value typed as number | boolean (parentheses added to emphasize this is one expression):

return (a ? 4 : true); // return number | boolean

That's fine. There's no other return statements the type needs to be in common with.

Second example - Multiple return statements

The second example has multiple return statements...

if (a) {
    return 4; // return number
} else {
    return true; // return boolean
}

... and no common type exists among the multiple statements. So it errors.

Solution with multiple return statements

When no common type exists between the return statements, you need to be explicit in order to let the compiler know you mean to do this:

function foo(a: boolean): number | boolean {
    if (a) {
        return 4;
    } else {
        return true;
    }
}

Related: See "Best Common Type"

like image 74
David Sherret Avatar answered Oct 27 '22 11:10

David Sherret