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

Incorrect type inference of tuple when underlying array is extended #13941

Closed
anfedorov opened this issue Feb 7, 2017 · 7 comments
Closed

Incorrect type inference of tuple when underlying array is extended #13941

anfedorov opened this issue Feb 7, 2017 · 7 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@anfedorov
Copy link

TypeScript Version: 2.1.5

Code

let x: [string, number];

x = ["hello", 10];
x[3] = 'hi';

let y = x[2];
if (y == null) {
    console.log('yes ever');
    y;
}

screen shot 2017-02-07 at 3 23 32 pm

$ node static/build/js/test.js 
yes ever

Expected behavior:

Before reading the docs, I would expect the type checker to find an error on line 4.

Given the feature set defined in the docs, I would expect the type at line 4 to be let y : undefined.

Actual behavior:

Type is incorrectly inferred as let y : never.

@anfedorov anfedorov changed the title Incorrect type inference of tuple when it is extended Incorrect type inference of tuple when underlying array is extended Feb 7, 2017
@aluanhaddad
Copy link
Contributor

aluanhaddad commented Feb 8, 2017

Using --strictNullChecks and typescript@2.1.5, the type of y is string | number, outside of the if statement, and never inside of it.
The inference of never is correct and expected because y is not not nullable, and therefore the block will never execute.
With respect to the inferred type of the array element, I believe it is covered by the proposal in #6229

@anfedorov
Copy link
Author

But the block does execute and the code compiles without warnings or errors, even with --strictNullChecks:

code $ cat test.ts
let x: [string, number];

x = ["hello", 10];
x[3] = 'hi';

let y = x[2];
if (y == null) {
    console.log('yes ever');
    y;
}
code $ tsc --strictNullChecks test.ts 
code $ node test.js
yes ever

Thanks for the reference to the proposal — that is indeed a little closer to the behavior I would have expected.

@aluanhaddad
Copy link
Contributor

@anfedorov Ah, I see your point now. I misread it as y === null which would not be taken. It seems there may be a bug here, but I am not sure.

@anfedorov
Copy link
Author

anfedorov commented Feb 8, 2017

Yup, y is undefined, and the proposal you linked might be the most elegant fix.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 27, 2017

unfortunately there is no way to do this correctly in the general case, e.g.: for (var z = 0, z<10, z++) x[z];. you can also find more details in #13778 on why the index signature intentionally, does not include undefined.

@mhegazy mhegazy added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Apr 27, 2017
@anfedorov
Copy link
Author

copying tuple behavior from Python seems like one way to handle it. i.e. x[3] = 'hi' could raise an error. another option is for x[3] = 'hi' to mutate the type of x to [string, number, undefined, string], fixing the error inside the if block.

this seems to work fine in the playground: https://www.typescriptlang.org/play/index.html#src=let%20x%3A%20%5Bnumber%2C%20string%2C%20undefined%2C%20number%5D%3B%0D%0Ax%20%3D%20%5B1%2C%20'1'%2C%20undefined%2C%202%5D%3B%0D%0A%0D%0Ax%5B3%5D%20%3D%202%0D%0Ax%5B2%5D%20%3D%203%0D%0A

regardless, x[z] just like x[prompt()] could be string | number | undefined?

@mhegazy
Copy link
Contributor

mhegazy commented May 22, 2017

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@mhegazy mhegazy closed this as completed May 22, 2017
@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
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants