# Fun Times with Advanced TypeScript

by **Nicola Marcacci Rossi**

This article is meant for people who know the basics of TypeScript but haven’t used it in a large project, and/or haven’t explored its advanced types.

My goal is to convince you, based on a ton of examples, that TypeScript’s powerful advanced type system can provide satisfying solutions for complex web engineering problems and can be used for mind-blowing and fun modeling.

Watch this video and refer to code snippets below.

**Building Blocks**

These are types you can find on the official TypeScript documentation. They are the building blocks for more advanced/fancy stuff. Think of this section as a cheat-sheet.

**Intersection types**

Get all members from multiple types:

If you think of types as sets, what you get here is the intersection of two types, which is a smaller set. This can be confusing as the actual resulting type has a “larger” interface, i.e. the union of the members of both types.

**Union types**

Get common members from multiple types (the resulting type is the union between the two, i.e. a larger set):

**Custom Type Guards**

Conditional type cast:

With the *is* keyword you can define functions to determine “by hand” whether a value belongs to a type, and TypeScript then assumes that type in the true part of a conditional statement.

**Type Assertion**

A cast shorthand if you know that a specific variable is definitely defined:

**Literal Types**

You can use actual primitive literals (strings, booleans etc.) as types:

If you think of types as sets, the type `'ROCK'`

is the set containing only the value `'ROCK'`

.

**Never**

An expression that never resolves:

This type will magically appear in many surprising spots in the examples below.

**Unknown**

A safer type than any for variables that you can’t trust:

**Index Types**

Access the types of object keys or values:

**Mapped Types**

Derive an object type from another:

This powerful abstraction will make more sense when you see specific applications of it.

**Conditional Types**

Let a type depend on another type with a condition:

Here’s an actual application for conditional types:

With the infer keyword you can introduce a type variable, the type of which will be inferred:

**Misc Patterns**

**Functional Programming**

This is not exactly related to advanced types, rather it’s an illustration of how one can program in a lightweight but type safe way with TypeScript. In Java world, in the Clean Code paradigm there are two main categories of classes: *objects* and *data types*. Data types represent data (think getters and setters), while objects represent functionality (think methods). With TypeScript one can simplify this approach even more by just using *interfaces* to represent data and *functions* to manipulate data. No bulky boilerplate, no constructors, getters and setters needed. Just return a plain object and typescript will ensure it is correctly structured.

**Discriminate Unions**

TypeScript understands you have exhaustively checked all possible variants of a type in a switch statement, and won’t force you to use a default statement.

**Derive Types From Constants**

Often we need literal types both as values and as types. To avoid redundancy derive the latter from the former.

**Untrusted User Input**

Untrusted user input is an application for unknown.

**Mapped Types**

Create a readonly version of a type:

Derive a partial version of a type:

Derive a version of a type where all fields are required:

Derive a nullable version of a type:

Derive a type with only specific fields (Pick):

An example from practice, where we select specific columns from a SQL table, and TypeScript automatically derives the partial type for us:

Derive a record (all properties have same given type) from a type:

**Conditional Types**

**Filter union types**

Filter / extract a subset from a type:

Diff / exclude a subset from a type:

Exclude null and undefined from a typed (thus making it non-nullable):

Omit specific fields from a type:

Here is an example from practice (how to type a React.js HOC correctly):

**Combining with mapped types**

Get the function properties of an object:

Get the non-function properties of an object:

Get the return type of a function:

Get the instance type of a constructor function:

**Promisifying Redis**

Another example from practice. All methods in the npm redis library use callbacks. We like to use promises and async/await. We can derive the new type from the old based on how we build it.

**Conclusion**

I hope to have convinced you of the power of TypeScript. Now go ahead and TYPE!