typescript passes `number | Promise<number>` as if it were `number` (or something like that)
See original GitHub issueBug Report
Something is very weird that makes typescript pass Promise<number>
as if it were a number
when it is an object field. Typescript correctly recognizes that Promise<number>
is not a number when it is a plain variable. Weird.
🔎 Search Terms
promise numeric
🕗 Version & Regression Information
I believe this has always existed in typescript. I have tried multiple versions on playground (from 3.3 up to 5). I did read the FAQs in https://github.com/Microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs and found nothing related.
⏯ Playground Link
Playground link with relevant code
💻 Code
const n: number | Promise<number> = Promise.resolve(0);
console.log(n >= 0); // Correctly rejected: Operator >= cannot be applied to Promise<number> and number.
const foo: {n: number | Promise<number>} = {
n: Promise.resolve(0),
};
console.log(foo.n >= 0); // Incorrectly type checks. Runtime result is bogus.
🙁 Actual behavior
The last expression passes the type checker even though it is clearly wrong.
🙂 Expected behavior
That the last expression is rejected with Operator >= cannot be applied to Promise<number> and number.
.
Issue Analytics
- State:
- Created 9 months ago
- Comments:8 (1 by maintainers)
Top Results From Across the Web
Type 'Promise<number>' is not assignable to type 'number'
I'd like to add a little thing. async functions are considered as promises so what getId used to return is actually the promise...
Read more >Keep Your Promises in TypeScript using async/await
This function takes a number of milliseconds and returns a Promise that gets resolved using setTimeout after the given number of milliseconds.
Read more >Documentation - TypeScript 4.3
The problem is that size allows you to assign more than just number s to it. We could get around this by saying...
Read more >You are not logged in. Reading 22: Promises
The Promise type in TypeScript is generic: a Promise<T> represents a concurrent computation that ... diskSpace(folder:string) returning a Promise<number> .
Read more >How to type an async Function in TypeScript | bobbyhadz
type GetNumber = (num: number) => Promise<number>; // ✓ Arrow function with ... The type we passed to the Promise generic is the...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I’ve checked what happens under the hood and it seems that it’s enough for left and right types to be comparable in either direction: https://github.dev/microsoft/TypeScript/blob/c7f49bceed878d751701f018d066fffc5926e3b0/src/compiler/checker.ts#L35641
This is quite surprising but apparently it’s even OK to compare class instances (test case taken from the TS test suite): TS playground
I spiked a potential improvement for the reported case here but I’m not totally sure if this is something that the TS team would like to incorporate.
Thanks for explaining the difference @fatcerberus. (though it’s also weird that it narrows despite my explicit type specification but let’s not get distracted)
Now why
number | Promise<number>
typechecks is still the issue.