7 Subtyping
In this chapter
- Disambiguating types in TypeScript
- Safe deserialization
- Values for error cases
- Type compatibility for sum types, collections, and functions
Now that we covered primitive types, composition, and function types, it’s time to look at another aspect of type systems: relationships between types. In this chapter we’ll introduce the subtyping relationship. While you might be familiar with it from object-oriented programming, we will not cover inheritance in this chapter. Instead, we will focus on a different set of applications of subtyping.
We’ll first talk about what subtyping is, and the two ways in which programming languages implement it: structural and nominal. We will then revisit our Mars Climate Orbiter example and explain the unique symbol trick we used in chapter 4, when discussing type safety.
Since a type can be a subtype of another type and it can also have other subtypes itself, we will look at this type hierarchy: we usually have a type which sits at the top of this hierarchy and, sometimes, a type which sits at the bottom. We’ll see how we can use this top type in a scenario like deserialization, where we don’t have a lot of typing information readily available. We’ll also see how we can use a bottom type as a value for error cases.