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

Number literal type allows increment #14745

Closed
mihailik opened this issue Mar 20, 2017 · 10 comments
Closed

Number literal type allows increment #14745

mihailik opened this issue Mar 20, 2017 · 10 comments
Labels
Won't Fix The severity and priority of this issue do not warrant the time or complexity needed to fix it

Comments

@mihailik
Copy link
Contributor

mihailik commented Mar 20, 2017

TypeScript Version: 2.2.1 / Playground

Code

var s10: 10 = 10;
s10++;
s10 += 1;
s10 = s10 + 1; // Type 'number' is not assignable to type '10'.

Expected behavior:
Compiler errors on all three lines

Actual behavior:
Only errors on the last line.

This looks like a clear bug. A bit more subtle case is a union of literals where increment may or may not lead to the correct type. That subtlety should probably be folded into integer types, and ignored for now. Increments and += on literal type should error.

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Mar 20, 2017
@mhegazy mhegazy added the Help Wanted You can do this label Mar 20, 2017
@mhegazy mhegazy added this to the Community milestone Mar 20, 2017
@ghost
Copy link

ghost commented Feb 16, 2018

(Resubmitting comment as had initially submitted under a different github account name)

I happened on precisely this bug today & am pleased to find it's a known problem.

@mhegazy I would be willing to help out on this issue if someone with compiler internals knowledge would be kind enough to give me a few pointers on what source files need to be addressed. I have a basic feel for getting around the compiler code having contributed a tiny PR a year or two ago. Thanks for any tips on getting started!

@DanielRosenwasser
Copy link
Member

@indiescripter go for it! Everything you need should be in checker.ts where we check against binary and unary expressions.

We also need a new error message like

The literal type '{0}' cannot be modified.

So go ahead and add that into diagnosticMessages.json and run jake generate-diagnostics.

@ghost
Copy link

ghost commented Feb 22, 2018

Thanks @DanielRosenwasser for the heads up. I'll give it a go in slow time, in-between other commitments.

@weswigham
Copy link
Member

FYI,

var s10: 10 | 11 = 10;
s10++;

could be construed as probably valid code. We just don't do any similar analysis right now (and made a design choice not to).

@collin5
Copy link
Contributor

collin5 commented Oct 21, 2018

@indiescripter Are you still working on this? Would love to give this a try if otherwise.

@ghost
Copy link

ghost commented Oct 21, 2018

Hi @collin5, thanks for asking. Unfortunately due to some very sad family events a while back I've had to drop all activities like this. Please be my guest and pick it up. It would be a nice & intellectually rewarding task if you want to take it on. Let me know how goes.
Cheers Justin J.

@collin5
Copy link
Contributor

collin5 commented Oct 21, 2018

Sorry about that. Will be starting on this soon. Thank you!

@collin5
Copy link
Contributor

collin5 commented Nov 5, 2018

I've created a Pull request to resolve this #28344

@ahejlsberg
Copy link
Member

Some thoughts on this issue...

While it doesn't seem unreasonable to disallow increment, decrement, and compound assignment operators on variables of unit types, it also doesn't seem particularly useful. It just isn't meaningful or common to declare mutable variables of unit types (what would be the point?) so we wouldn't be solving a real world problem.

The real scenario is the semantics of applying those operators to variables of literal union types, i.e. unions of unit types. I don't think it is feasible to just error here--after all, it is perfectly fine to increment a value of type 0 | 1 | 2. Rather, in order to do better we would have to support "type math", i.e. reflecting the effects of the built-in operators on sets of possible values. For example, incrementing a value of type 0 | 1 | 2 should yield a value of type 1 | 2 | 3. However, this quickly gets unwieldy when both operands are union types. For example, multiplication of two values of literal union types with n and m possible values would produce a literal union type with n * m possible values.

We have previously decided not to do this because the added complexity (conceptual and in implementation) doesn't justify the marginal gains in type checking. I think this decision still holds, so I'm not sure we really want to do anything here.

@mihailik
Copy link
Contributor Author

mihailik commented Feb 2, 2019

Better suggestion.

NO MUTATING operators on ANY literal types.
Fine to have mutating operators on unions, those have funky use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Won't Fix The severity and priority of this issue do not warrant the time or complexity needed to fix it
Projects
None yet
Development

No branches or pull requests

7 participants