Blog / Typescript

How to Use Advanced TypeScript Types: keyof, Mapped Types, Conditional Types

How to Use Advanced TypeScript Types: keyof, Mapped Types, Conditional Types

In this post find out about how to Use Advanced TypeScript Types: keyof, Mapped Types, Conditional Types

Will MaygerWill Mayger
May 27, 2023
Article

TypeScript is a powerful superset of JavaScript that introduces static typing and advanced type features to enhance developer productivity and code reliability. While basic types and interfaces in TypeScript provide a solid foundation, there are advanced type features like keyof, mapped types, and conditional types that allow for even more expressive and flexible type definitions. In this article, we’ll explore these advanced TypeScript types and demonstrate how they can be utilized effectively in your code.

1. Understanding keyof

The keyof operator in TypeScript allows you to extract the keys of an object type. It returns a union of string literal types representing the keys present in the given type. Let’s see an example:

type Person = {
  name: string;
  age: number;
  address: string;
};

type PersonKeys = keyof Person; // "name" | "age" | "address"

In the above example, PersonKeys is a type that represents the keys "name", "age", and "address" from the Person type. This is particularly useful when you want to create generic functions or utilities that operate on object properties dynamically.

2. Working with Mapped Types

Mapped types in TypeScript allow you to transform or manipulate existing types to create new ones. They provide a concise way to iterate over the properties of an object type and make modifications based on a pattern. Let’s explore a couple of examples:

Example 1: Readonly properties

type ReadonlyPerson = {
  readonly [K in keyof Person]: Person[K];
};

const person: ReadonlyPerson = {
  name: "John",
  age: 25,
  address: "123 Main St"
};

person.name = "Jane"; // Error: Cannot assign to 'name' because it is a read-only property.

In the above example, we create a new type ReadonlyPerson using a mapped type. By using the readonly modifier and keyof Person, we ensure that all properties of ReadonlyPerson are readonly, mirroring the properties of the original Person type.

Example 2: Partial properties

type PartialPerson = {
  [K in keyof Person]?: Person[K];
};

const partialPerson: PartialPerson = {
  name: "John"
};

Here, we define a PartialPerson type using a mapped type. The ? operator makes all properties optional, allowing us to create an object with only a subset of properties from the original Person type.

3. Exploring Conditional Types

Conditional types in TypeScript allow you to create type definitions that depend on a condition. They enable you to define different types based on the properties or relationships of other types. Let’s see an example:

type Filter<T, U> = T extends U ? T : never;

type StringOrNumber = string | number;
type OnlyNumbers = Filter<StringOrNumber, number>; // number

In the above example, the Filter type takes two generic parameters T and U. It checks if T extends U and returns T if true, otherwise never. In this case, Filter<StringOrNumber, number> evaluates to number, effectively filtering out any non-numeric types.

4. Advanced Techniques with Advanced Types

Now that we have explored the individual advanced TypeScript types, let’s look at how they can be combined to achieve more complex type definitions. Here are a couple of examples:

Example 1: Indexing into a mapped type

type PersonInfo<T extends keyof Person

> = {
  label: T;
  value: Person[T];
};

function getProperty<T extends keyof Person>(prop: T): PersonInfo<T> {
  return {
    label: prop,
    value: person[prop]
  };
}

const nameInfo = getProperty("name");
console.log(nameInfo.value); // "John"

In this example, we define a PersonInfo type that takes a generic type T, which extends keyof Person. It represents information about a specific property of Person, including the property name (label) and its corresponding value (value). The getProperty function retrieves the property value based on the provided key and returns an object of PersonInfo type. We then obtain the name information by calling getProperty("name"), and access the value using nameInfo.value.

Example 2: Extracting subset of properties

type ExtractProperties<T, U> = {
  [K in keyof T]: K extends U ? T[K] : never;
};

type PersonSubset = ExtractProperties<Person, "name" | "age">;

In this example, we create a ExtractProperties type that takes two generic parameters T and U. It constructs a new type by iterating over the properties of T using a mapped type. If the property key extends U, it includes the property in the resulting type; otherwise, it assigns never to that property. The PersonSubset type extracts a subset of properties from Person by specifying the desired keys "name" and "age".

Conclusion

Advanced TypeScript types like keyof, mapped types, and conditional types provide powerful capabilities to create expressive and precise type definitions. By leveraging these features, you can enhance the type safety and maintainability of your codebase. Whether it’s extracting keys, transforming types, or conditionally defining types, these advanced TypeScript types empower you to handle complex scenarios with ease. Take advantage of these techniques and unlock the full potential of TypeScript in your projects.

There we have how to Use Advanced TypeScript Types: keyof, Mapped Types, Conditional Types, if you want more like this be sure to check out some of my other posts!

Foxi - Budget Planner & Tracker

Foxi

Budget Planner & Tracker

More money in your pocket by the end of the month.

Free to use and no account needed.

Get started now.

Get the app

Some graphics used on this post were made using icons from flaticon.

Latest Posts

Learn React, JavaScript and TypeScript

Learn React, JavaScript and TypeScript

Join the platform that top tier companies are using.
Master the skills you need to succeed as a software engineer and take your career to the next level with Pluralsight.

Start here

Become an expert in ReactJS, TypeScript, and JavaScript.

Here you will find my personal recomendations to you, for full disclosure I earn a small commission from some of these links, but I only recommend what I trust and personally use.

Good things are coming, don't miss out!

Good things are coming, don't miss out!

Follow me on Twitter to stay up to date and learn frontend, React, JavaScript, and TypeScript tips and tricks!

Are you a novice, intermediate or expert react engineer?

Find out here by taking my fun, interactive, quick quiz which takes approximately 1 - 3 minutes. How well will you will do?

Foxi - Budget Planner & Tracker

Foxi

Budget Planner & Tracker

More money in your pocket by the end of the month.

Free to use and no account needed.

Get started now.

Get the app