Search code examples
typescripttype-narrowing

Negative user-defined type guards


function isFish(pet: Fish | Bird): pet is Fish {
    return (<Fish>pet).swim !== undefined;
}

tells typescript that pet type is Fish

Is there a way to state the contrary, that the input parameter is NOT a Fish?

function isNotFish(pet: Fish | Bird): pet is not Fish {  // ????
       return pet.swim === undefined;
}

Solution

  • You can use the Exclude conditional type to exclude types from a union :

    function isNotFish(pet: Fish | Bird): pet is Exclude<typeof pet, Fish>    
    { 
        return pet.swim === undefined;
    }
    

    Or a more generic version :

    function isNotFishG<T>(pet: T ): pet is Exclude<typeof pet, Fish>    { 
        return pet.swim === undefined;
    }
    interface Fish { swim: boolean }
    interface Bird { crow: boolean }
    let p: Fish | Bird;
    if (isNotFishG(p)) {
        p.crow
    }