Skip to content

if/typeof guards on union type's uncommon properties #21944

Closed
@massimonewsuk

Description

@massimonewsuk

TypeScript Version: 2.7.0

Search Terms:
typeof union narrowing properties

Code

interface Bird {
    fly: () => any;
    layEggs: () => any;
}

interface Fish {
    swim: () => any;
    layEggs: () => any;
}

function Move(pet: Fish | Bird) {
    if (pet.swim) {
        pet.swim();
    } else {
        pet.fly();
    }
    
    if (typeof pet.swim === "function") {
        pet.swim();
    } else {
        pet.fly();
    }

    if ("swim" in pet) {
        pet.swim();
    } else {
        pet.fly();
    }
}

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions