-
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
if/typeof guards on union type's uncommon properties #21944
Comments
The danger here is that you write interface Bird {
fly: () => any;
layEggs: () => any;
}
interface Fish {
swim: () => any;
layEggs: () => any;
gills: number;
}
const puffin = {
fly: () => undefined,
swim: () => undefined,
layEggs: () => undefined
}
Move(puffin);
function Move(pet: Fish | Bird) {
if (pet.swim) {
pet.gills; // undefined, danger
}
} We don't want to make property access appear safe unless it actually is; property access in an The |
I understand that this is working as intended, as per the current TypeScript documentation. I actually prefer this approach to anything else that's currently available because Anyway, playing devil's advocate or purist or whatever you like, I'll continue... I logged an issue with Flow facebook/flow#5816 featuring the same code example, and I feel like their approach (whilst also not intuitive) is more "safe". In my mind, the following 3 alternative approaches sound relatively consistent:
|
This was the behavior prior to #10485. The change was well-received; I don't think this option is a "local maximum".
This is #21732
Clippy-style "linting" isn't really a thing we do because there's not an ergonomic way to dismiss it and say "No I did mean to do what I did there". |
Idiomatic JavaScript is, arguably, duck typing:
I’d love for the property check to receive equivalent treatment to the |
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.7.0
Search Terms:
typeof union narrowing properties
Code
Expected behavior:
I expect the code above to work without any errors at all. I feel it's all reasonable.
Actual behavior:
I get an error for the first 2 if/else branches, where I am accessing the property
swim
. The last branch works fine. I'm aware of the possibility of having a user-defined type guard function, but I don't want to have to do that.Playground Link:
https://www.typescriptlang.org/play/index.html#src=interface%20Bird%20%7B%0D%0A%20%20%20%20fly%3A%20()%20%3D%3E%20any%3B%0D%0A%20%20%20%20layEggs%3A%20()%20%3D%3E%20any%3B%0D%0A%7D%0D%0A%0D%0Ainterface%20Fish%20%7B%0D%0A%20%20%20%20swim%3A%20()%20%3D%3E%20any%3B%0D%0A%20%20%20%20layEggs%3A%20()%20%3D%3E%20any%3B%0D%0A%7D%0D%0A%0D%0Afunction%20Move(pet%3A%20Fish%20%7C%20Bird)%20%7B%0D%0A%20%20%20%20if%20(pet.swim)%20%7B%0D%0A%20%20%20%20%20%20%20%20pet.swim()%3B%0D%0A%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20pet.fly()%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20%0D%0A%20%20%20%20if%20(typeof%20pet.swim%20%3D%3D%3D%20%22function%22)%20%7B%0D%0A%20%20%20%20%20%20%20%20pet.swim()%3B%0D%0A%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20pet.fly()%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20if%20(%22swim%22%20in%20pet)%20%7B%0D%0A%20%20%20%20%20%20%20%20pet.swim()%3B%0D%0A%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20pet.fly()%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A
Related Issues:
Couldn't find any
The text was updated successfully, but these errors were encountered: