-
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
Unknown types narrowed to a union won't narrow further #30557
Comments
Narrowing by discriminant only applies when the declared type of the identifier is a union type; here, the declared type of There are probably good reasons for this that someone more knowledgeable can provide, performance possibly among them. There is an easy workaround which is declaring a new identifier inside the body of the first condition, then narrowing from that. |
Personally, I wish this was the way #27706 might be related. |
interestingly this works: function WorksProperly(data: Type) {
if (data.Name === "TypeA") {
// data: TypeA
const value1 = data.Value1;
}
}
function DoesNotWork(data: unknown) {
if (isType(data)) {
WorksProperly(data); // <-- !!!
// if (data.Name === "TypeA") {
// // data: Type
// // data should be TypeA
// const value1 = data.Value1;
// }
}
} |
I’m pretty certain the linked issue is not related. The behaviour as I describe is consistent with @Aleksey-Bykov ‘s example. The declared argument type of While it is nice to have full reasoning applied to every situation, TypeScript gains a lot of performance wins by judiciously picking when and where to apply expensive checks. I think this might be one of those cases, but I’m not certain. Someone on the team will be able to correct me. I’ll add that I do agree that your example would be nice to have, and iteratively narrowing |
what i've been told one day here is that narrowing doesn't make new types it only narrows what's given, in case of |
This feels like it might be a bug. Once |
Fix here #30593 |
Out of curiosity, is this related? I didn't have to use type Foo = Bar | Baz;
interface Bar {
kind: 'Bar';
prop: string | void;
}
interface Baz {
kind: 'Baz';
prop: string;
}
function fn(el: Foo): number {
switch (el.kind) {
case 'Bar':
if (!el.prop) {
return 0;
}
// falls through
case 'Baz':
return el.prop.length; // Property 'length' does not exist on type 'string | void'
}
} |
This fails on the playground, and I believe it also fails on [email protected]
TypeScript Version: [email protected]
Search Terms: unknown intersection failure types narrow
Code
Expected behavior: in
DoesNotWork
,data
should be TypeA after we can guarentee it is named "TypeA"Actual behavior:
data
is still only aType
Playground Link: Here
Related Issues: I looked through several pages of issues and did not find anything similar.
The text was updated successfully, but these errors were encountered: