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

non-null assertion not working on type parameter with constraint #20974

Closed
ajafff opened this issue Jan 2, 2018 · 6 comments
Closed

non-null assertion not working on type parameter with constraint #20974

ajafff opened this issue Jan 2, 2018 · 6 comments
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@ajafff
Copy link
Contributor

ajafff commented Jan 2, 2018

TypeScript Version: 2.7.0-dev.20171230

Code

function takeString(p: string) {}

function foo<T extends string | undefined>(param: T) {
  takeString(param!); // error on this line
}

Expected behavior:
Because of the constraint the compiler knows the type of param can only be string | undefined. Asserting the type with a non-null assertion should result in string and the code should compile without error.

If this is working as intended, I'll write a lint rule to warn about non-null assertions on type parameters.

Actual behavior:

Argument of type 'T' is not assignable to parameter of type 'string'.
  Type 'string | undefined' is not assignable to type 'string'.
    Type 'undefined' is not assignable to type 'string'.
@RyanCavanaugh
Copy link
Member

Asserting the type with a non-null assertion should result in string

We would need subtraction types to do this correctly. The correct type isn't string (because T might be instantiated with some type like "foo" | "bar"), it's T - undefined.

@ajafff
Copy link
Contributor Author

ajafff commented Jan 2, 2018

@RyanCavanaugh makes sense. So this is basically a duplicate of #4183?

@RyanCavanaugh RyanCavanaugh added Revisit An issue worth coming back to Suggestion An idea for TypeScript labels Jan 2, 2018
@RyanCavanaugh
Copy link
Member

Not a duplicate since this case wouldn't start working automatically

@ajafff
Copy link
Contributor Author

ajafff commented Mar 6, 2018

@weswigham Is this fixed by #22096 or #22348?

@weswigham
Copy link
Member

#22096 should cover it.

@mhegazy mhegazy added Fixed A PR has been merged for this issue and removed Revisit An issue worth coming back to labels Mar 6, 2018
@mhegazy mhegazy added this to the TypeScript 2.8 milestone Mar 6, 2018
@mhegazy mhegazy closed this as completed Mar 9, 2018
@weswigham
Copy link
Member

Oh, in case anyone happens to hit this again in the future: The new (more correct) behavior is dependent on the presence of the global NonNullable<T> type. If that's not there (because your compilation doesn't include the standard lib or includes an old one), it'll fall back to the older less-correct behavior (and consequently have the same problems). So if you still encounter this issue in TS 2.8+, double check that you've got the latest lib in your build!

@microsoft microsoft locked and limited conversation to collaborators Jul 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants