question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

typescript passes `number | Promise<number>` as if it were `number` (or something like that)

See original GitHub issue

Bug 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:open
  • Created 9 months ago
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
Andaristcommented, Dec 29, 2022

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.

1reaction
azizghuloumcommented, Dec 28, 2022

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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found