Typescript type restriction based on another value – how to apply this restriction in an array
When working with TypeScript, you may encounter a scenario where you need to apply a type restriction on an array based on another value. This can be useful in situations where you want to ensure that certain elements of the array meet specific criteria.
In this blog post, we will explore two solutions to achieve this type restriction in TypeScript arrays.
Solution 1: Using Union Types
One way to apply a type restriction based on another value in an array is by using union types. Union types allow us to define a type that can be one of several types.
Let’s say we have an array of objects representing different shapes:
type Shape = { type: 'circle', radius: number } | { type: 'rectangle', width: number, height: number } | { type: 'triangle', base: number, height: number };
const shapes: Shape[] = [
{ type: 'circle', radius: 5 },
{ type: 'rectangle', width: 10, height: 20 },
{ type: 'triangle', base: 8, height: 12 },
{ type: 'circle', radius: 3 },
];
We can then define a type restriction based on the shape type using conditional types:
type CircleShapes = Extract;
type RectangleShapes = Extract;
type TriangleShapes = Extract;
Now, we can create new arrays that only contain shapes of a specific type:
const circleShapes: CircleShapes[] = shapes.filter(shape => shape.type === 'circle');
const rectangleShapes: RectangleShapes[] = shapes.filter(shape => shape.type === 'rectangle');
const triangleShapes: TriangleShapes[] = shapes.filter(shape => shape.type === 'triangle');
This way, we have successfully applied a type restriction based on the shape type in the array.
Solution 2: Using Discriminated Unions
Another approach to apply a type restriction based on another value in an array is by using discriminated unions. Discriminated unions allow us to define a type that includes a discriminant property, which can be used to determine the specific type.
Let’s modify our shape example to use discriminated unions:
type CircleShape = { type: 'circle', radius: number };
type RectangleShape = { type: 'rectangle', width: number, height: number };
type TriangleShape = { type: 'triangle', base: number, height: number };
type Shape = CircleShape | RectangleShape | TriangleShape;
const shapes: Shape[] = [
{ type: 'circle', radius: 5 },
{ type: 'rectangle', width: 10, height: 20 },
{ type: 'triangle', base: 8, height: 12 },
{ type: 'circle', radius: 3 },
];
Now, we can use the discriminant property to apply the type restriction:
const circleShapes: CircleShape[] = shapes.filter(shape => shape.type === 'circle');
const rectangleShapes: RectangleShape[] = shapes.filter(shape => shape.type === 'rectangle');
const triangleShapes: TriangleShape[] = shapes.filter(shape => shape.type === 'triangle');
By using discriminated unions, we can easily apply the type restriction based on the shape type in the array.
Conclusion
When you need to apply a type restriction based on another value in an array, TypeScript provides multiple solutions. In this blog post, we explored two approaches: using union types and using discriminated unions. Both solutions allow you to define specific types within the array based on a certain value, ensuring type safety and better code organization.
Leave a Reply