-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Type Inference for Mapped Union Types Fails #19897
Comments
if (typeof y === "number") {
z.push(y);
}
else {
z = z.concat(y);
} |
I don't think I understand. |
@fongandrew There are two different things named type MapToNum<T> = {
[K in keyof T]?: number|Array<number>;
}; and the other is the javascript if (y instanceof Array) { If you are using an IDE and use go to declaration on both of those Most arrays you use in javascript are instances of the
|
@mhegazy Although confusingly everything I said apparently explicitly doesn't work if the things aren't generic so maybe this isn't working as intended? Compare: function test1(y: number | number[]) {
let z: number[] = [];
if (y instanceof Array) {
z = z.concat(y);
} else {
z.push(y) // no error
}
}
function test2<T extends number | number[]>(y: T) {
let z: number[] = [];
if (y instanceof Array) {
z = z.concat(y);
} else {
z.push(y) // error
}
} See #1719 #17344 #18498 for explanations why there's no error in non-generic case. I'm not a fan of typescript doing the narrowing in the else block since the MobX array thing is a common real world problem but it looks like that has already been considered and decided the other way so maybe it should be consistent between the generic and non-generic cases? |
@kpdonn That is, it's this inconsistency that I don't get. This works. type Generic<T> = {
numOrArray: number | number[];
other: T;
};
function test<T>(g: Generic<T>) {
let y = g.numOrArray;
let z: number[] = [];
if (y instanceof Array) {
z = z.concat(y);
} else {
z.push(y); // Works
}
} But this doesn't. type Generic<T extends string> = {
[key in T]: number | number[];
};
function test2<T extends string>(g: Generic<T>, key: T) {
let y = g[key];
let z: number[] = [];
if (y instanceof Array) {
z = z.concat(y);
} else {
z.push(y); // Errors
}
} |
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed. |
TypeScript Version: 2.6.1 / 2.7.0-dev20171109
Code
Expected behavior:
instanceof Array
should narrownumber|number[]|undefined
tonumber[]
and theelse if (y)
should narrow further tonumber
.Actual behavior: Narrowed to
any[]
andnumber|number[]
respectively.The text was updated successfully, but these errors were encountered: