Skip to content

type checking after instainceOf condition in else block is working incorrectly #5523

Closed

Description

see example in playground

interface IFoo {
    value: string[]|string;
}

function bar(options: IFoo) {
    var val = options.value;
    var result: string;
    if (val instanceof Array) {
        result = val.join('')
    } else {
        result = val;
    }
}

val has one of two types strting[] or string
in 'if' condition checked instanceofArray
in else statement compiler should know that val has string type

Activity

  1. sandersn commented on Nov 4, 2015

    @sandersn
    Member

    #5442 should fix this, I think.

  2. weswigham commented on Nov 4, 2015

    @weswigham
    Member

    #5442 only has changes typeof type guards and composite type guards.

    But this behavior is actually by spec - with instanceof type guards, we only affirmatively narrow (so in the true branch) - the logic being that since TS uses structural typing, even if instanceof catches something, instanceof not catching something doesn't mean that the thing you're checking is not a given type. (In effect, val instanceof Array does not imply that val does not have the type of an array, since it could still have the shape of an array but not the same constructor.) User-defined type guards are more strict, as we assume when you make a type predicate that it's capable of being exhaustive, and typeof is more strict because primitives are effectively nominal.

    In the example above, if you do this:

    interface IFoo {
        value: string[]|string;
    }
    
    function bar(options: IFoo) {
        var val = options.value;
        var result: string;
        if (typeof val !== "string") {
            result = val.join('')
        } else {
            result = val;
        }
    }

    it will narrow as you desire. Prefer typeof to instanceof where possible because of this.

  3. RyanCavanaugh commented on Nov 4, 2015

    @RyanCavanaugh
    Member

    #1719 is the issue for this

  4. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions