The following TypeScript code will not compile:
interface ZeroFunc {
(value: string): string;
(value: number): number;
}
const zero: ZeroFunc = (value: string | number) =>
typeof value === 'string' ? '' : 0;
The error:
Type '(value: string | number) => "" | 0' is not assignable to type 'ZeroFunc'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'. ts(2322)
It seems to be complaining about the return type.
The error makes sense, even though the function is implemented correctly.
Is there a way to correctly specify the type of this function, without using any
as the return type?
Is it possible at all to implement the ZeroFunc
interface correctly?
Here's a better illustration of the problem:
function zero(value: string): string;
function zero(value: number): number;
function zero(value: string | number): string | number {
return typeof value === 'string' ? '' : 0;
}
type ZeroFunc = typeof zero;
const zero2: ZeroFunc = (value: string | number): string | number {
return typeof value === 'string' ? '' : 0;
}
The declaration of zero2
has the same error as above. But clearly, they're the exact same function signatures. I literally just copy-pasted it.
The type ZeroFunc
even has the exact same definition as my interface above.
It seems like this is going to be an error unless this proposal gets implemented: https://github.com/microsoft/TypeScript/issues/34319
Having function implements
would essentially solve this issue.
See also: https://github.com/microsoft/TypeScript/issues/37824
In particular, from this comment:
[...] in #6075 we added a special bivariance check between return types of overloads and implementations. It's an unsound laxness, but it allowed people to model these cases more easily.
We didn't add this check for the general case of checking assignability between a function to a type with overloads because it wasn't clear if the intent was going to be the same.
In other words, the example with plain function
really shouldn't compile either, but it was allowed because otherwise things would just be way too annoying.
For function assignments, it wasn't allowed, because it would be way easier to break things, and the benefits didn't outweigh the risks.