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

Improved union type guards #1657

Merged
merged 4 commits into from
Jan 13, 2015
Merged

Improved union type guards #1657

merged 4 commits into from
Jan 13, 2015

Conversation

ahejlsberg
Copy link
Member

Fixes #1587.

This PR improves handing of union types in type guards. Specifically, when a type guard of the form x instanceof C is true, the type of x is narrowed as follows:

  • If C is a subtype of the type of x, the type of x is narrowed to C.
  • Otherwise, if x is of a union type, all types that are not subtypes of C are removed from the type of x.

In the example

class Message {
    value: string;
}

function saySize(message: Message | Message[]) {
    if (message instanceof Array) {
        return message.length;  // message of type Message[] here
    }
}

the Message type is removed under the type guard because it is not a subtype of Array.

@JsonFreeman
Copy link
Contributor

👍

ahejlsberg added a commit that referenced this pull request Jan 13, 2015
@ahejlsberg ahejlsberg merged commit cbecae3 into master Jan 13, 2015
@danielearwicker
Copy link

Note that (x instanceof Array) !== Array.isArray(x) in cross-window situations, though not that common these days.

@battmanz
Copy link

If I modify the code as follows and add an else block, why does the compiler think that the type of message inside that else block is Message | Message[]? Shouldn't it only be Message?

class Message {
    value: string;
}

interface MessageHandler {
    handle(message: Message): void;
}

function saySize(message: Message | Message[], handler: MessageHandler) {
    if (message instanceof Array) {
        message.forEach(m => handler.handle(m));
    }
    else {
        handler.handle(message); // Argument of type 'Message | Message[]' is not assignable to parameter of type 'Message'.
    }
}

@danquirk
Copy link
Member

@battmanz see #1719

@mhegazy
Copy link
Contributor

mhegazy commented Sep 28, 2015

@battmanz this is tracked by #1719

@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Type Guard syntax for array
7 participants