-
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
Inferring Intersection Types #8911
Comments
Type guards don't magically widen types. The only narrow types. You made it clear that If you wanted it to work, you would have to let the compiler know that // two interfaces
interface A {
a: string;
}
interface B {
b: string;
}
// a type guard for B
function isB(toTest: any): toTest is B {
return toTest && toTest.b;
}
// a function that turns an A into an A & B
function union(a: A | (A & B)): A & B {
if (isB(a)) {
return a; // compiler correctly assumes `a` is not just `A` but is `A & B` and
// gives no error
} else {
return null;
}
} |
Hm. Is there an issue with soundness? I know that |
Yes, but you said |
Why does it have to stop being an |
@leeavital Rewrite your type guard like so for the behavior you want: interface A {
a: string;
}
interface B {
b: string;
}
// a type guard for B
function isB<T>(toTest: T): toTest is (T&B) {
return toTest && (toTest as any).b;
}
// a function that turns an A into an A & B
function union(a: A): A & B {
if (isB(a)) {
return a;
} else {
return null;
}
} TS only narrows a type to a subtype - it never narrows 'across', as it were. |
With the nightly build compiler, the type of The operating principle for type guards is that they only "narrow" the type, i.e. they only make the type more specific. Type guards never change the type to something unrelated such as from I think you're suggesting we should allow "narrowing across" to unrelated types and then produce an intersection of the declared type and the tested-for type (i.e. |
Reopening as suggestion. More examples of this feature in #9016. |
I'm coming around to the view that we should produce intersection types in type guards for unrelated types. In particular, given that It's a pretty simple change. I will look at putting up a PR. |
TypeScript Version:
1.8.10
Code
Expected behavior:
I would expect this to compile successfully.
Actual behavior:
Inside the if-block, tsc has "forgotten" about the A-ness of
a
. This is a useful pattern ifb
is an expensive property to compute and you want to do different things ifb
is or is not present.The text was updated successfully, but these errors were encountered: