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?
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
}
}