Skip to content

RHS expression type in assignment incorrectly inferred #3123

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
yjbanov opened this issue May 12, 2015 · 7 comments
Closed

RHS expression type in assignment incorrectly inferred #3123

yjbanov opened this issue May 12, 2015 · 7 comments
Labels
Duplicate An existing issue was already created

Comments

@yjbanov
Copy link

yjbanov commented May 12, 2015

To completely fix #1587 TypeScript should also support:

function repro(message: Object | Object[]) {
    if (message instanceof Array) {
        message = message.filter;  // error
    }
}

Currently it results in Property 'entries' does not exist on type 'Object | Object[]'. It seems message on the RHS switches from Array back to Object | Object[] prematurely.

Workaround:

function workaround(message: Object | Object[]) {
    var theMessage = message;
    if (theMessage instanceof Array) {
        message = theMessage.filter;
    }
}
@danquirk
Copy link
Member

The current design is that type guards narrow down the known constituent types of a union type, but they don't narrow to anything just based on the instanceof operator. Otherwise there'd be no need to use a union type here at all, you could just type message as any and let type guards do the rest.

@yjbanov
Copy link
Author

yjbanov commented May 12, 2015

I thought that was what my example did, narrow down the constituents of the union type. Here's another example:

class Uri {
    uriString: String;
 }

function repro(uri: String | Uri) {
    if (uri instanceof Uri) {
        uri = uri.uriString; // error
    }
}

function workaround(uri: String | Uri) {
    var theUri = uri;
    if (theUri instanceof Uri) {
        uri = theUri.uriString;
    }
}

I certainly wouldn't want to type uri as any.

@DanielRosenwasser
Copy link
Member

I believe the reason you're getting issues in both examples is because type-guards don't narrow variables in scopes where you assign to those variables.

@yjbanov
Copy link
Author

yjbanov commented May 12, 2015

@DanielRosenwasser, that's what it feels like to me too. It seems to assign one type to the entire code block, in this case the if block. It doesn't recognize that before the assignment the type guard is in effect, and after the assignment the variable acquires a different type.

@danquirk
Copy link
Member

Sorry, I misread the original example. @DanielRosenwasser is right, the issue is related to the assignment rule we have for type guards.

@DanielRosenwasser DanielRosenwasser added By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Question An issue which isn't directly actionable in code and removed By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Question An issue which isn't directly actionable in code labels May 12, 2015
@RyanCavanaugh
Copy link
Member

Basically duplicate of #2388, then?

@yjbanov
Copy link
Author

yjbanov commented May 13, 2015

@RyanCavanaugh, pretty close. Could be used as another test case.

@mhegazy mhegazy added the Duplicate An existing issue was already created label May 21, 2015
@mhegazy mhegazy closed this as completed May 21, 2015
@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
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants