All Things Typescript Newsletter - Better Type Safety with Discriminated Unions - Issue #9
Good morning; I hope you had a great weekend. I apologize for not sending last week’s issue; I was feeling unwell and could not publish an issue for the week. In this issue, we will look into writing types with better type safety using Discriminated Unions and will have curated tweets and articles from the last two weeks.
I hope you have a great week ahead, and don’t forget to follow me on Twitter - @mwycliffe_dev and if you have any questions, ideas, or feedback, my DMs are open to everyone.
Better Type Safety with Discriminated Unions
If we want to get the most out of Typescript Types, we need to ensure that we are specific in how we define them. A loosely defined type might be better than not having them, but their impact will not be as good as having Types that properly reflect our data.
Let’s take the simplest example I can think of - Shapes. You get the idea in shapes; we can have Circles, Rectangles, Squares, etc. You cannot have a single type alias covering all shapes without compromising on something.
If we were to define a Shape
type alias for just the above three shapes, it would need to account for the possibility that all fields are not there for all shapes, i.e., Circle only has a radius, which doesn’t exist in either Rectangle or Square, while the circle doesn’t have either width or height. As you can imagine, our problem becomes more extensive as you add more shapes.
So, our type alias would look like this.
type Shape = {
radius?: Number; // For Circle
length?: Number; // For Rectangle
width?: Number; // For Rectangle
side?: Number; // For Square side Length
}
From the above example, the type alias above is not very useful since if you had a circle, you could easily leave out all fields or add all of them to Shape
and typescript will not be able to help you at all; all it can do is offer autocompletion hints for you.
And discriminated unions come to the rescue.
Discriminated Unions
Instead of defining a single type alias that loosely much all of our possible types, we can define three different types, each containing a literal field member indicating what shape we have.
For instance, the type for Rectangle would look like this:
type Rectangle = {
shape: "Rectangle",
length: number;
width: number;
}
And the same applies to both Circle and Square:
type Circle = {
shape: "Circle"
radius: number;
}
type Square = {
shape: "Square";
side: number;
}
And then, we can use a union of the three to declare a type alias of shape that can only be a single type of the above.
type Shape = Square | Rectangle | Circle;
Usage
Now, with our new Type shape, we have to indicate the shape field, and then typescript is going to use the shape field value to determine the fields that are required for the Type you are creating.
For instance, the shape Circle can only contain a radius property, and if you tried to add, let’s say, width, you will get an error:
const x: Shape = {
shape: "Circle",
radius: 5,
width: 5, // Error ---> Object literal may only specify known properties, and 'width' does not exist in type 'Circle'.
}
This offers a much better type safety as the shape field can now be strictly enforced depending on which you want, and you can now narrow the types based on the field shape.
if(shape.shape === "Circle") {
// the type is now a Circle only
}
This gives you peace of mind when using and creating objects compared to the loosely defined type we had initially.
I hope you found today’s lesson illuminating, and if you have any questions, please feel free to reach out to me.
Announcement 📢
Announcing TypeScript 4.7 RC - TypeScript
Today we’re excited to announce our Release Candidate (RC) of TypeScript 4.7! Between now and the stable release of TypeScript 4.7, we expect no further changes apart from critical bug fixes. To get started using the RC, you can get it through NuGet,
Meta Open Source is transferring Jest to the OpenJS Foundation
Transferring ownership of Jest is an exciting and natural next step as Jest matures as an open-source project.
Nx v14 is out - Here is all you need to know! - DEV Community
All the awesome features that went into Nx v14. Tagged with react, angular, javascript, nx.
Lerna is dead — Long Live Lerna. If you’re in a hurry, here’s the TL;DR: | by Juri Strumpflohner | May, 2022 | Nrwl
We (Nrwl) are the company behind Nx (GitHub) and we have been founded by two ex-Googlers and Angular core team members Jeff Cross and Victor Savkin. Experiencing a large-scale monorepo in action at…
Top Articles 📙
Meaningful Object Keys in TypeScript - Netanel Basal
In Typescript, Record is a common way to express an object type. For example:
How to pass a TypeScript function as a parameter
What is a TypeScript function type? Using argument numbers in TypeScript Typing our functions example in TypeScript As a programming language, JavaScript relies on the concept of First-Class functions, meaning that functions are treated like any other variable, such as a number, string, or array.
What Type of Safety Can You Get with TypeScript on Web Rush #183
Maarten Tibau talks with us about the benefits of Type Safety when working with TypeScript. What is type safety? Does the presence of types alone make you safe? How do you make projects more type safe?
Why You Should Avoid Using Type Assertion in TypeScript - Netanel Basal
You’ve probably used the as type assertion at least once when working with Typescript. For example:
The Difference between Import, Export, and Require in JavaScript | by Johnny Simpson | May, 2022 | JavaScript in Plain English
What does all of this mean?! And why are there so many ways to seemingly import packages in JavaScript? And why can’t I get import to work on my Node.js server? Let’s explore what it all means. Out…
How the TypeScript ReturnType Type works | by Johnny Simpson | May, 2022 | JavaScript in Plain English
The ReturnType in TypeScript is a utility type which is quite similar to the Parameters Type. It let’s you take the return output of a function, and construct a type based off it. The ReturnType…
The Observant Developer — Part 1. Like tests, observability tools provide… | by Roni Dover | May, 2022 | Better Programming
Historically, observability was never high on developer teams’ worry lists. Coding features is what developers do, and observability doesn’t sound much like code at all (I have written previously…
The saddest "Just Ship It" story ever
This is a story of how it took me way too long to ship a product, and I ended up paying for a competitor product instead.
Semantic Versioning for TypeScript Types
A specification for managing changes to TypeScript types, including when the TypeScript compiler makes breaking changes in its type-checking and type emit across a “minor” release.
A Frameworkless Store In TypeScript | by David Dal Busco | May, 2022 | Better Programming
There are undeniable advantages to using frameworks (React, Angular, Svelte etc.) for frontend development but there are also undeniable disadvantages. The interoperability and compatibility between…