-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Incorrect type inference #31741
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
Comments
The value If you adjust to declaration of const v: Type = 42 as Type;
if (isN(v)) {
const n: number = v;
} else {
const s: string = v;
} |
Note that the complex types here are just a distraction; it reproduces fine with |
Thanks for the quick response, guys! Unfortunately, I tried to create a minimal example based on a much more complex code, where the issue has originated, I guess it became too simple to reproduce ) I've updated the example with a little bit more complexity. |
Ah ok. Yes I think something is not right here. The checker thinks that const i: Interface<unknown> = { data: "hello" };
let j: Interface<Type.N> = { data: 3 }
j.data = i.data; // error
j = i; // no error This is likely related to #31295 because you get the correct behaviour if you use two identical but differently named aliases. enum Type { N, S }
interface Interface<E extends Type | unknown = unknown> {
type?: Type
data?: // just for an idea of how the E parameter is used
E extends Type.N ? number :
E extends Type.S ? string :
number | string
}
interface Interface2<E extends Type | unknown = unknown> {
type?: Type
data?: // just for an idea of how the E parameter is used
E extends Type.N ? number :
E extends Type.S ? string :
number | string
}
const isN = (i: Interface): i is Interface2<Type.N> => i.type === Type.N;
const i: Interface<unknown> = { data: "hello" };
let j: Interface2<Type.N> = { data: 3 }
j.data = i.data; // error
j = i; // error
if (isN(i)) {
i // i is Interface2<Type.N>
} else {
i // i is Interface<unknown>
} |
This is an effect of the type checker deciding that You could consider including an optional property that witnesses interface Interface<E = unknown> {
// ...
__E__?: E;
} This causes the type checker to measure the interface as co-variant in |
Awesome, @ahejlsberg, thanks for your help! |
TypeScript Version: 3.3.3333
Search Terms:
typescript type guard else never
Code
Related Issues:
#17789
#10934
The text was updated successfully, but these errors were encountered: