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.
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?
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!