We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Instead of writing this:
type DataType = {
type: "idle" | "loading" | "done" | "error" | "invalid";
};
const obj: DataType = {
type: "idle"
};
if (obj.type === "idle") {
// ...
} else if (obj.type === "loading") {
// ...
} else if (obj.type === "done") {
// ...
} else if (obj.type === "error") {
// ...
} else if (obj.type === "invalid") {
// ...
}
You can use the ts-pattern library to write it like this instead:
import { match } from "ts-pattern";
type Result = {
type: "idle" | "loading" | "done" | "error" | "invalid";
};
const result: Result = { type: "error" };
match(result)
.with({ type: "idle" }, () => console.log("idle"))
.with({ type: "error" }, () => console.log("error"))
.with({ type: "done" }, () => console.log("error"))
.exhaustive();
I personally find the latter a lot more readable, less verbose and easier to understand.
It even allows you to do things like this:
import { match, P } from 'ts-pattern';
type Data =
| { type: 'text'; content: string }
| { type: 'img'; src: string };
type Result =
| { type: 'ok'; data: Data }
| { type: 'error'; error: Error };
const result: Result = ...;
const html = match(result)
.with({ type: 'error' }, () => <p>Oups! An error occured</p>)
.with({ type: 'ok', data: { type: 'text' } }, (res) => <p>{res.data.content}</p>)
.with({ type: 'ok', data: { type: 'img', src: P.select() } }, (src) => <img src={src} />)
.exhaustive();
It's almost a nice as pattern matching in Elixir.
You can find more examples and the full explanation here.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.