Uncommon TypeScript Features
For the last couple of months I’ve been working with TypeScript a lot. Many cool features came to my mind and now I see more ways to use them. Here I would like to share some interesting features of TypeScript that I find interesting but not really common. None of these features are super unique(some of them could be even found in docs)
Enumeration
TypeScript allows you to create a union of types like so
type Coffee = Latte | Espresso | Americano
. And this even works with strings or numbers like
type Coffee = “latte” | “americano”
and
type CoffeeId = 1 | 2 | 3
However this gets worse if you need to specify a big range of numbers. In this case if you don’t want to check your range conditionaly, you may find it usefull to create an IntRange type:
type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N
? Acc[number]
: Enumerate<N, [...Acc, Acc['length']]>
type IntRange<F extends number, T extends number>
= Exclude<Enumerate<T>, Enumerate<F>>
const num: IntRange<20, 300> = 200 // It's Ok
const num: IntRange<20, 300> = 1000 // This will give you an error
Required and Partial
Those three types are actually from . But among many others I find them particularly usefull.
The Required is a type wrapper that makes all fields… well… required. This way you can make something like:
type Coffee = { // Say, you found this type in readonly library
coffeeBeans: Beans,
steamedMilk?: true,
hotChocolate?: true,
};
//////////////////////////////
type Mocha = Required<Coffee>;
//const mocha: Mocha = { // Error, hotChocolate is not specified
// coffeeBeans: Beans.Columbia,
// steamedMilk: true,
//};
const mocha: Mocha = { // It's Ok
coffeeBeans: Beans.Columbia,
steamedMilk: true,
hotChocolate: true,
};
Partial does exactly the oposite making all your fields optional. That’s especially usefull when you are going to update some entity and you don’t want to provide all the types of existing one:
type Entity = {
name: string,
description: string
}
///////////////
function updateEntity(id: string, newEntity: Partial<Entity>) {
db.findEntity(id).update(newEntity);
}
///////////////
updateEntity(id, {description: {'New Description'})
Type of array elements
One time you may want to retrieve type of an array element. You can do this with the next type:
type ArrayElement<ArrayType extends readonly unknown[]> =
ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
Check out thread for more
Last Updated: October 30th, 2022