Unions and Narrowing 28 exercises
Problem

Handling Separate But Related Types

This Shape type includes a kind attribute which is always defined as a string, as well as optional radius and sideLength attributes, which are both numbers:

type Shape = {
  kind: string;
  radius?: number;
  sideLength?: number;
};

The calcuateArea function takes in a

Loading exercise

Transcript

00:00 In this exercise, we have a type called shape, and this shape type has a kind attribute, which is a string, which is always defined. And then we have a radius, which is possibly defined and is a number, and then side length, which is also maybe defined and is a number.

00:17 Then we have a calculate area function below. This calculate area function takes in a shape, which is a type shape. And we say if shape.kind equals circle, then we return math.py times the radii, and then we're good to go. We're off to the races.

00:33 And then otherwise, if it's a shape.sideLength, we assume it's a rectangle instead, and then we just times the shape.sideLength times shape.sideLength. So you can imagine this is a kind of polymorphic function, which takes in two separate shapes.

00:47 And we've got some tests down below. We're expecting the test to pass if we calculate the area of the circle correctly. So this type annotation, though, is really bugging me, because we can actually pass in a bunch of illegal stuff into here.

01:04 We can say calculate area, and we can pass in a kind that doesn't exist. We can give both a radius and a side length, which just should not be possible. There must be a better way that we can express this logic.

01:20 So I'll give you a clue. In fact, I'll give you two words. Discriminated unions is the thing you need to look up. And by doing that, you're going to discover a really interesting way to describe this shape property.

01:34 It's going to use the union symbol that we've covered before, and it's going to also test your knowledge of narrowing as well. Good luck.