Home > Mobile >  How to discriminate an union against "never" type?
How to discriminate an union against "never" type?

Time:06-17

Let's say I have this union:

type TShape = {
    id: string;
}

type TCircle = TShape & {
    radius: number;
    size: never;
}

type TSquare = TShape & {
    radius: never;
    size: number;
}

The problem is how to discriminate the two possible types (in this case) using the radius field, for instance:

function getArea(shape: TCircle | TSquare): number {
    if (typeof shape.radius === "number") {
        return shape.radius * shape.radius * Math.PI;
    }
    else {
        return shape.radius * shape.size;  //no error?
    }
}

What I expect is a compiler error on the last calculation, because the radius field never exist on the TSquare type.

What's wrong with this and how to solve this problem?

CodePudding user response:

Since TSquare does not need radius field you can declare it without it

type TSquare = TShape & {
    size: number;
}

Then you can modify function and check if radius is defined.

function getArea(shape: TCircle | TSquare): number {
    if ("radius" in shape) {
        return shape.radius * shape.radius * Math.PI;
    }
    else {
        return shape.radius * shape.size;  // this should be an error this time
    }
}
  • Related