DEV Community

Dharan Ganesan
Dharan Ganesan

Posted on

3 1 1 2 1

Day 49: Conditional Types

What are Conditional Types?

Conditional types are a TypeScript feature introduced in version 2.8 that enable you to define types based on conditions. They allow you to express complex type relationships and create reusable type logic. Conditional types are defined using the extends keyword and the ? operator, making them highly versatile.

Basic Syntax

Let's start with the basic syntax of a conditional type:

type MyConditionalType<T> = T extends U ? X : Y;
Enter fullscreen mode Exit fullscreen mode
  • T is the type parameter we want to test.
  • U is the type we're checking T against.
  • X is the type that MyConditionalType evaluates to if the condition is true.
  • Y is the type that MyConditionalType evaluates to if the condition is false.

Understanding the Condition

The condition in a conditional type can be any valid type operation or expression. Commonly used operations include keyof, extends, and infer. Here's a breakdown of some common condition types:

  • keyof: Checks if a type has a specific key.
  • extends: Tests if a type extends another type.
  • infer: Extracts a type from another type.

Basic Examples

Conditional Type with extends

type IsString<T> = T extends string ? true : false;

const a: IsString<"Hello"> = true; // true
const b: IsString<42> = false;     // false
Enter fullscreen mode Exit fullscreen mode

In this example, IsString<T> checks if T extends (is assignable to) the string type. If so, it returns true, otherwise false.

keyof and Index Signatures

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

interface Person {
  name: string;
  age: number;
  email: string;
}

type StringKeys = KeysOfType<Person, string>; // "name" | "email"
Enter fullscreen mode Exit fullscreen mode

Here, KeysOfType<T, U> generates a new type that contains keys from T whose corresponding values extend U. In our Person interface, it extracts keys with values of type string.

Advanced Examples

Mapping Union Types

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

type OnlyStrings = FilterByType<string | number | boolean, string>; // "string"
Enter fullscreen mode Exit fullscreen mode

This example creates a type that filters out all non-U types from a union type T.

Inferring Function Parameters

type FirstParam<T> = T extends (param1: infer P, ...args: any[]) => any ? P : never;

function greet(name: string, age: number) {
  return `Hello, ${name}! You are ${age} years old.`;
}

type NameParam = FirstParam<typeof greet>; // string
Enter fullscreen mode Exit fullscreen mode

Here, FirstParam<T> extracts the type of the first parameter of a function. In this case, it infers string from the greet function.

Built-in Conditional Types

TypeScript provides several built-in conditional types that simplify common type operations.

Exclude

Exclude<T, U> removes all types from T that are assignable to U.

type Excluded = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
Enter fullscreen mode Exit fullscreen mode

Extract

Extract<T, U> extracts all types from T that are assignable to U.

type Extracted = Extract<"a" | "b" | "c", "a" | "b">; // "a" | "b"
Enter fullscreen mode Exit fullscreen mode

NonNullable

NonNullable<T> removes null and undefined from T.

type NotNullable = NonNullable<string | null | undefined>; // string
Enter fullscreen mode Exit fullscreen mode

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more