This compiles without error in TypeScript 2.1.5:
function promiseANumber(): Promise<number> {
return new Promise(resolve => resolve('definitely not a number'));
}
I would expect an error to be reported, since the resolve function is called with a string instead of a number, as per the type definition.
Why is this type mismatch not caught and reported by TypeScript's compiler?
Looking at this a bit more, using an async function definition instead, the compiler correctly reports the type mismatch. So this:
async function promiseANumber(): Promise<number> {
return 'definitely not a number';
}
gives
error TS2322: Type '"definitely not a number"' is not assignable to type 'number'.
Why do these cases behave differently?
It looks like the way to make the compiler correctly catch this it to explicitly tell it which type of promise you're returning. So this is sufficient:
function promiseANumber() {
return new Promise<number>(resolve => resolve('definitely not a number'));
}
which the compiler now complains about:
error TS2345: Argument of type '"definitely not a number"' is not assignable to parameter of type 'number | Thenable<number>'.
I suppose my question is now, why can't the compiler infer this, given the definition I gave at the beginning of this question?
Happily, TypeScript 2.4 now indicates the correct error for my original code! It's due to it now supporting return types as inference targets. That announcement even has a code sample very similar to the example I gave initially.
In this case...
function promiseANumber(): Promise<number> {
return new Promise(resolve => resolve('definitely not a number'));
}
...the reason why resolve does not expect number
is because it's specified as being {}
when writing new Promise(...)
because that's the default type of new Promise()
. The compiler then allows the assignment for Promise<{}>
to Promise<number>
... that itself is questionable.
In this case...
async function promiseANumber(): Promise<number> {
// type returned is Promise<string>, doesn't match Promise<number>
return 'definitely not a number';
}
...the type returned is Promise<string>
and that doesn't match Promise<number>
so the compiler throws an error.
In your example with the promise, you can tell the compiler to define the promise as Promise<number>
by doing:
function promiseANumber(): Promise<number> {
return new Promise<number>(resolve => resolve('definitely not a number'));
}
...which will cause a compile error because string
is not assignable to number
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With