See this and many other articles at lucaspaganini.com
Conditional types in TypeScript are super powerful, they allow us to create type functions. I'll show you.
Let's say we have 3 types:
type A type B type C
They could be anything, but let's say that
C is the union of
type A = string; type B = number; type C = A | B;
Now, we want to convert
number to literal numeric representations.
string should be
type NumberA = 1; type NumberB = number; type NumberC = 1 | number;
number should be
2, and anything else should be
type NumberA = 1; type NumberB = 2; type NumberC = 1 | 2;
If this was a function, you would simply use conditionals to drive the code. It would look something like this:
const ToNumber = (T) => (T === string ? 1 : T === number ? 2 : 0);
That syntax doesn't work for types, but it's pretty close.
type ToNumber = (T) => T === string ? 1 : T === number ? 2 : 0
Instead of an arrow, we use equals.
type ToNumber(T) = T === string ? 1 : T === number ? 2 : 0
Instead of parenthesis, we use angle brackets.
type ToNumber<T> = T === string ? 1 : T === number ? 2 : 0
And instead of triple equals, we use extends.
type ToNumber<T> = T extends string ? 1 : T extends number ? 2 : 0;
See, we are not asking TypeScript if
T is equal to
string, what we're asking is if
T is a subset of
That also includes literal string types, such as
type A = string type B = number type C = A | B ToNumber<A> // -> 1 ToNumber<B> // -> 2 ToNumber<C> // -> 1 | 2 ToNumber<boolean> // -> 0 ToNumber<"abc"> // -> 1
References are below.
This article is part of my TypeScript Narrowing Series. You can read the full series for free on my blog.
Leave a like, have a great day, and I'll see you soon!