-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Update expressions with untyped argument are typed number
, not number | bigint
#49558
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Related: #41741 |
Okay, didn't find that one, probably because it has been closed 🤷♂️ |
Also related: #42125 |
The part of #47741 that is related: The problem described here for update expressions ( const anyNegate1 = (myUntypedBigInt: any): number => -myUntypedBigInt; also does not give a type error, although it should, while const anyNegate2 = (myUntypedBigInt: number | bigint): number => -myUntypedBigInt; correctly reports a type error. |
Almost all numerical operators are affected. Given that: let x: any = 0n All these statements return the type
These statements return the type
This statements returns the type
|
Dealing with this issue too! Can't do any numerical operations with using bigint |
This is also a problem with generics: // ❌
const f = <T extends number | bigint,>(x: T): T => -x
// ✅
const g = <T extends number | bigint,>(x: T) => -x as T The type-assertion is silly |
Sorry to disagree, but it isn't. This error is not related to
So what happens here? In TypeScript, there are subtypes of Note that const f = (x: number|bigint): number|bigint => -x; does not result in a type error, but you could argue that it is unprecise, because it doesn't state that a Thus, I'd suggest to use an overloaded function in this case, like so: function f(x: number): number;
function f(x: bigint): bigint;
function f(x: number|bigint): number|bigint {
return -x;
} Then, |
Correct! That was an oversight on my part
Thanks for the info! I've already known about overloads, but I decided to avoid them because I thought generics were "better practice" than overloads. Being a Rust dev doesn't help, as we're forced to use generics |
If you want to avoid overloads and still want to declare precise input->output type mappings, you can use conditional types instead. In the example from above, this would look like so: function f<T extends number|bigint>(x: T): T extends number ? number : bigint {
return -x as any;
} I actually prefer overloads in most case, because even though they are lengthy, they make the different usages of the same function clearer, and you can even add different TSDoc to each overload, while with conditional types, the one signature quickly becomes complex and you have to explain all usages in one documentation block. But it really depends on the use case and on personal taste. Also, as you can see in the example, implementing a function with a conditional return type often results in having to use an |
Bug Report
Update expressions (
++
,--
) with an untyped (any
) argument are typed asnumber
, not asnumber | bigint
.This results in missing and incorrect type errors.
🔎 Search Terms
label:Bug bigint
🕗 Version & Regression Information
Support for
bigint
has been introduced with TypeScript 3.2.The bug is still present in TypeScript 4.7.2 and today's Nightly (15/06/2022).
It seems the edge case this issue describes has just been overlooked.
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
For
anyInc1
, there is no type error, although the result of the expression at run-time may be abigint
when the argument is abigint
(e.g.anyInc1(42n)
).For
anyInc2
, there is the type erroralthough the correct type of the update expression,
number | bigint
, does overlap withbigint
.🙂 Expected behavior
The resolved type of applying any update expression operator (
++
,--
, pre- or postfix) on an untyped expression should benumber | bigint
, notnumber
.Then,
anyInc1
would result in the correct type errorAs a side-note, using
number | bigint
instead ofany
as the parameter type correctly results in exactly that type error:anyInc2
would no longer result in a type error.The text was updated successfully, but these errors were encountered: