Skip to content

bang operator resets type inference #16945

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

Open
amir-arad opened this issue Jul 5, 2017 · 4 comments
Open

bang operator resets type inference #16945

amir-arad opened this issue Jul 5, 2017 · 4 comments
Labels
Bug A bug in TypeScript
Milestone

Comments

@amir-arad
Copy link

TypeScript Version: 2.3.4

Code

type Foo = {
  foo:string;
};
function isFoo(arg?:any):arg is Foo|undefined{
    return true;
}
function logic(arg?:object){
    if (isFoo(arg)){
        arg.foo;  //Error:(..., 13) TS2532:Object is possibly 'undefined'. 
        arg!.foo; //Error:(..., 18) TS2339:Property 'foo' does not exist on type 'object'.
    }
}

Expected behavior:
arg! should resolve to foo if it's already inferred that arg is Foo|undefined
Actual behavior:
arg! is resolved to object

@DeDuckProject
Copy link

How about a double bang?

argggg!!!!!!.foo;

@amir-arad amir-arad changed the title band operator resets type inference bang operator resets type inference Jul 5, 2017
@kitsonk
Copy link
Contributor

kitsonk commented Jul 5, 2017

Why would you create a custom type guard that included undefined? That doesn't sound very realistic.

@amir-arad
Copy link
Author

amir-arad commented Jul 5, 2017

It isn't a realistic example, but it's a clear and simple reproduction of inference information that gets lost by using the bang operator. The real-life scenario is a lot messier.

consider this example then:

function isFoo(arg?:any):arg is Foo{
    return true;
}
function logic(arg?:object, b?:boolean){
    if (isFoo(arg)){
        arg = b? undefined : arg;
        if (!b) {
            arg.foo; //Error:(..., 13) TS2532:Object is possibly 'undefined'. 
            arg!.foo; //Error:(..., 18) TS2339:Property 'foo' does not exist on type 'object'.
        }
    }
}

@DanielRosenwasser
Copy link
Member

I think there are some problems with how object gets narrowed in general. For example:

interface Foo {
    foo;
}

declare function isFooMaybe(x: any): x is Foo | undefined;

declare var a: object | undefined;
if (isFooMaybe(a)) {
    var b = a // (object & undefined) | (object & Foo)
}

@DanielRosenwasser DanielRosenwasser added Bug A bug in TypeScript Needs Investigation This issue needs a team member to investigate its status. labels Jul 6, 2017
@DanielRosenwasser DanielRosenwasser added this to the TypeScript 2.5 milestone Jul 6, 2017
@DanielRosenwasser DanielRosenwasser removed the Needs Investigation This issue needs a team member to investigate its status. label Aug 29, 2017
@mhegazy mhegazy modified the milestones: TypeScript 2.6, TypeScript 2.7 Oct 9, 2017
@mhegazy mhegazy modified the milestones: TypeScript 2.7, TypeScript 2.8 Jan 9, 2018
@mhegazy mhegazy modified the milestones: TypeScript 2.8, TypeScript 2.9 Mar 9, 2018
@mhegazy mhegazy assigned weswigham and unassigned sandersn Apr 26, 2018
@mhegazy mhegazy modified the milestones: TypeScript 3.0, TypeScript 3.1 Jul 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

9 participants