Skip to content
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

Unary minus on 'any' should infer type to 'number | bigint', not just 'number' #60914

Open
tbroyer opened this issue Jan 5, 2025 · 3 comments
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@tbroyer
Copy link

tbroyer commented Jan 5, 2025

πŸ”Ž Search Terms

"unary minus", "negate bigint"

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about bigint

⏯ Playground Link

https://www.typescriptlang.org/play/?target=99&ts=5.7.2#code/MYewdgzgLgBARjAvDAtACgIxgJQG4BQA9ITKTAHoD8+okscATEqnAcWRdTeNDGM+gx4iJMlW50+TZCjBtRpcRN4BDAFwwVYAJ7NWIjuNq8AHgJXzDXY7FoA3Zmjsat27EgB8qO5bHUbMABOzPZocMLsfsq24HbSME4aYACuALZwAKbBAD7wAJYA5nlgUO6IXig+BlEBgfH2DGERCpz4QA

πŸ’» Code

const b = -(1n);
//    ^?
const b2 = -b;
//    ^?

const n = -(1);
//    ^?
const n2 = -n;
//    ^?

const a: any = b;
//    ^?
const x = -a;
//    ^?

const conv = (v: any) => -v;
//    ^?
const r = conv(b);
//    ^?
const conv2 = (v: number | bigint) => -v;
//    ^?
const r2 = conv2(b);
//    ^?

πŸ™ Actual behavior

Applying an unary minus on an any variable infers the type to number (as can be seen in the "hat-question mark" comments or the .D.TS tab for x, conv, and r). The inferred type for the constants x and r is thus wrong (they actually contain a BigInt value).

Unary minus on a number correctly infers number, and (more importantly) unary minus on a bigint correctly infers bigint. Same for unary minus on a number | bigint which infers number | bigint.

πŸ™‚ Expected behavior

Applying an unary minus on an any variable should infer the type to number | bigint.

ECMAScript specifies (https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-unary-minus-operator) unary minus as doing a ToNumeric (which returns either a Number of a BigInt) and then applying the appropriate unaryMinus abstract operation depending on the type of the value. The result is thus either a Number or a BigInt.

(the unary plus operator however converts to Number values only)

Additional information about the issue

No response

@MartinJohns
Copy link
Contributor

This is working as intended. See #41741.

@uhyo
Copy link
Contributor

uhyo commented Jan 5, 2025

Probably it's not a duplicate -- Answer from @RyanCavanaugh in that issue doesn't apply to the unary minus operator.

@tbroyer
Copy link
Author

tbroyer commented Jan 5, 2025

Related issues about operators and bigint #42125 and #49558

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants