Skip to content

Recent --strictNullChecks issue w/ && || type result check #9113

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

Closed
GoToLoop opened this issue Jun 13, 2016 · 6 comments
Closed

Recent --strictNullChecks issue w/ && || type result check #9113

GoToLoop opened this issue Jun 13, 2016 · 6 comments
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue

Comments

@GoToLoop
Copy link

About 1 weak ago, this sample below would transpile flawlessly under --strictNullChecks:

let sinOrCos = Math.random() < .5;

let choice = sinOrCos && Math.sin || Math.cos;
//let choice = sinOrCos? Math.sin : Math.cos;

alert(choice(Math.PI));

But to my surprise today, under [email protected], only the statement using the ternary conditional operator works now!

Somehow TS thinks that choice could be boolean as well when using && + || expression. =(
Is that intentional from now on? I miss when it was smarter just 1 week ago. :-(

tsc --pretty --newLine LF --removeComments --experimentalDecorators --strictNullChecks -d -t ES6 sinCos

@GoToLoop
Copy link
Author

GoToLoop commented Jun 13, 2016

1 more example:

function sq(n?: number): number {
  const r = n !== undefined && n*n || 0;
  return r;
}

alert(sq(3));

sq.ts(3,9): error TS2322: Type 'number | boolean' is not assignable to type 'number'.
Type 'boolean' is not assignable to type 'number'.

@kitsonk
Copy link
Contributor

kitsonk commented Jun 13, 2016

Like due to changes in #8949 which resolved #8892.

@ahejlsberg
Copy link
Member

I see what's going on here. The issue is that we give the sub-expression sinOrCos && Math.sin the type ((x: number) => number) | boolean. Since the result could be the boolean value false, this is technically not wrong. But it is a little bit too permissive. The type really should be ((x: number) => number) | false, meaning that the only the boolean value false is possible. We should likewise return T | 0 and T | "" for && operations where the first operand is of type number or string respectively.

Then we should furthermore say that in an x || y operation, we remove the definitely-falsy types (undefined, null, void, false, 0, and "") from the type of x in the resulting union type.

Now, the only problem with this solution is that we don't (yet) support boolean literal types or numeric literal types. This means we need to do one of the following:

Adding @mhegazy and @RyanCavanaugh.

@ahejlsberg ahejlsberg added the Bug A bug in TypeScript label Jun 13, 2016
@ahejlsberg ahejlsberg added this to the TypeScript 2.0 milestone Jun 13, 2016
@ahejlsberg ahejlsberg self-assigned this Jun 13, 2016
@zpdDG4gta8XKpMCd
Copy link

Add support for boolean and numeric literal types now.

👍

@zpdDG4gta8XKpMCd
Copy link

and numeric ranges:

type Positive = number > 0;

@GoToLoop
Copy link
Author

GoToLoop commented Jun 13, 2016

Numeric ranges? Are those even possible? That'd be über cool though.
I always wanted to use boolean literals for overloaded functions just like strings do.
I wonder whether those proposed numeric literals would include enums as well?
But of course the most important thing now is to have the && + || archaic idiom back under --strictNullChecks! :P

@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Jun 15, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue
Projects
None yet
Development

No branches or pull requests

5 participants