-
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
Union types could be reduced to their 'minimum valid' definitions #16644
Comments
I'm sorry, I don't work here or anything, just wanted to test your code, cause it seems to me like So I test it here However, I can't reproduce that issue you mention. It compiles both types as number[] (witch for me it's an unexpected behavior cause you explicit said that could be Moreover, if you set Also, if you use |
The reduction of union types to a constituent that is a common supertype already happens. Perhaps something is missing in your example? |
@RyanCavanaugh - Typescript is treating both of the types in my example differently (one's blowing up, another one doesn't). So it seems like I've managed to find some edge case maybe? |
Since |
@jcalz - sure, but |
No, not with var x: number[] | Array<number | undefined>;
var x: Array<number | undefined>; // error:
// Subsequent variable declarations must have the same type.
// Variable 'x' must be of type '(number | undefined)[] | number[]',
// but here has type '(number | undefined)[]'. EDIT: wait, maybe I see where you're going with this. Each value of type |
Okay, so you're saying that
Are you sure of this? |
@jcalz - precisely this. |
This error only happens if you set EDIT: Also, in this environment, However, this works as expected if the compiler is not in Example with primitives only Toggle strictNullCheck to see the error and the union typing changes |
@michaeljota no, this has nothing to do with undefined. Let's try a different one: var k = [1, 2, 3];
(k as number[]).filter(x => typeof x === 'string'); // fine
(k as (number | string)[]).filter(x => typeof x === 'string'); // fine
(k as number[] | (number | string)[]).filter(x => typeof x === 'string'); // error! The typechecker is not absorbing EDIT: however, arrays are mutable... so therefore |
If I understand the last message correctly, that would also mean that |
Maybe? Since typescript is perfectly fine assigning a value of type var a: number[] = [1,2,3];
var b: (number | string)[] = a;
b[0] = 'boom';
console.log(a[0]); So forget my previous edit, I guess. |
This is somewhat irrelevant to the issue at hand, but technically |
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.4.0
Code
Expected behavior:
Both examples compile.
Actual behavior:
The latter example fails with
Cannot invoke an expression whose type lacks a call signature. Type '{ (callbackfn: (this: void, value: number | undefined, index: number, array: (number | undefined)...' has no compatible call signatures.
Explanation
ExhaustiveType
andExcessiveType
both represent exactly the same types. The latter is more explicit, and while in this particular example it might look silly, w/ more complex types and type aliases, being more explicit allows for more expressivity. IMHO TypeScript could at the time of definingExcessiveType
, 'reduce it down' to theExhaustiveType
. Alternatively (to preserve expressiveness e.g. in the IDE), the compiler could internally treat them as equivalent.The text was updated successfully, but these errors were encountered: