typescript

Function union or function with return type of union


There's no difference for the programmer between the following two types:

declare let foo: () => number | string;
declare let bar: (() => number) | (() => string);

foo = bar;
bar = foo; // <- error.

Playground

Both variables can be invoked without arguments and the result will be either number or string.

So why aren't they assignable to each other?

Is this just a limitation, or intended design? Why would you want this complication?


Solution

  • I believe this behavior makes perfect sense when you think about it:

    declare let foo: () => number | string;  // Returns random type each call
    declare let bar: (() => number) | (() => string);  // Consistent return type
    

    The key difference is that foo might return different types on different calls, while bar must stick to one return type consistently.

    That's why foo = bar works (consistent functions are safe to use as random-returning ones), but bar = foo fails (can't guarantee a random-returning function will be consistent).

    It's not a limitation - it's TypeScript protecting you from potential runtime surprises!