TypeScript Advanced Typing Examples

Orelsanpls
4 min readDec 16, 2020

This article will show you throught examples how far you can go with TypeScript typing and maybe help you to improve your code.

Structure of this article :

1/ The examples are sorted by difficulty (easy first).

2/ The examples are first, the explainations follows.

Examples

#1 Inheritance rewrite

Difficulty : easy

#2 Deep inheritance rewrite

Difficulty : medium

#3 Type mutations

Difficulty : medium

#4 Optional nested key

Difficulty : hard

Explainations

#1 Inheritance rewrite

Let’s start with an easy example usingextends :

As you probably already know, using extends will makes Bar to contains every attributes defined in Foo . Now what if we wants to redifine keyB as a Dateinstead of a number ?

We would do :

But it does not work :

The soluce is to extendsevery key of Bar except keyB so it available to be declared as aDate :

#2 Deep inheritance rewrite

In this example, we seek to customize the Library interface, by changing the type of the attribute color in Books. And of course, we do not want to rewrite eveything !

As we saw in the first example, we use Omit<Library, 'books'> to specify which attribute we are going to rewrite.

Then, when rewriting books, we apply the same logic. Omit<Library['books'][0], 'color'> state that we wants to keep every attribute of books except color that we are going to rewrite.

The & here act as a concatenation of both types :

  • Everything inbooks except color
  • The new color definition

#3 Type mutations

We are here creating a new type, removing the readonly property of every first level variables. Example :

#4 Optional nested key

When you are dealing with MongoDB (NoSQL database), there a difference between the data you are pushing to the database and the data extracted from the database. MongoDB will automatically adds _id keys to your data.

It would be a shame to rewrite the whole interface. Instead, we will have a TypeScript type that will makes the _id keys to be optionals. One interface only.

Difficulty : hard

Let’s break down PartialK and NestedPartialK :

PartialK first is working on one level. It’s first argument T is the level to be treated. The second argument K contains the keys name’s to make optionals.

The expression :

1/ Extract<keyof T, K> returns the list of the keys that are declared in the object and inK . Example : If K is _id and the object doesnt contains the _id key, the Extract will returns nothing. Otherwise it would return _id .

2/ Pick<T, Extract<keyof T, K>> pick from the objects every keys that has matched in the Extract.

3/ Partial<Pick<T, Extract<keyof T, K>>> then we makes all theses keys optional.

In the following example, Example is worth { _id?: undefined | string }

4/ Using the & operator, we merge the object created before with a new object defined by Omit<T, K> extends infer O ? { [P in keyof O]: O[P] } : never

5/ Omit<T, K> will takes every keys on the object except the one in K which are the keys we want to turn optional.

6/ infer O ? { [P in keyof O]: O[P] } : never is sugar. We use it to force TypeScript interpretation. The code without the extends infer .... works :

But makes it terrible to use directly. TypeScript does not interpret it :

With extends infer .... and TypeScript interpretation, we get :

So how does it work ? The extends is a keyword that is forcing TypeScript to interpret the type. And we extends what ? The result of the & we calculated before. About the infer it is used to be able to specify to Typescript the data to extends.

About NestedPartialK : We loop on every key of the object

1/ In case the value behind the key is a Function , keep the data.

2/ In case the value behind the key is an Array , call NestedPartialK again (recursivity).

3/ In case the value behind the key is an object , call NestedPartialK again (recursivity).

End

This is the end of this article, thank you for reading it! I hope that you learned something new about TypeScript typing today :)

Special thanks

Thanks to jcalz in stackoverflow about NestedPartialK ! https://stackoverflow.com/questions/59845907/partial-on-specific-key

--

--