Sometimes we run into some code where we need to type a value as either one or the other. In this blog post, we will see how we can achieve this by leveraging TypeScript’s never type.
Let’s use shapes as an example. A shape can have a color, no matter what specific shape it is, but not every shape can have a radius or a side length. We could type it like this:
interface ShapeBase {
color: string;
}
interface Square extends ShapeBase {
sideLength: number;
}
interface Circle extends ShapeBase {
radius: number;
};
type Shape = Square | Circle;
The problem with this type definition is, that an object of type Shape
can have a color, side length and a radius without causing an error.
const myShape: Shape = {
color: 'red',
sideLength: 123,
radius: 987
}
How can we achieve that this object can either have a side length OR a radius, but not both?
For this to work, we have to leverage TypeScript’s never
type. This type tells Typescript that this property should never exist and therefore results in an error. If you want to read more about never, check out the TypeScript docs. We need to set both properties on both types and mark the unwanted property as optional and type it as never
.
interface Square extends ShapeBase {
sideLength: number;
radius?: never;
}
interface Circle extends ShapeBase {
radius: number;
sideLength?: never
};
type Shape = Square | Circle;
If we try to create an object of Type Shape with a radius
and sideLength
property, TypeScript now tells us that an error occurred:
As long as we only set one property, either radius
or sideLength
TypeScript won’t complain anymore.
Thank you,
Tim