TypeScript Conditional Types
Last Updated :
24 Jan, 2025
In TypeScript, conditional types enable developers to create types that depend on a condition, allowing for more dynamic and flexible type definitions.
- They follow the syntax T extends U ? X : Y, meaning if type T is assignable to type U, the type resolves to X; otherwise, it resolves to Y.
- Conditional types are particularly useful for creating utility types and for advanced type manipulations, enhancing code reusability and type safety.
JavaScript
type IsString<T> = T extends string ? 'Yes' : 'No';
type Test1 = IsString<string>;
type Test2 = IsString<number>;
console.log('Test1:', 'Yes');
console.log('Test2:', 'No');
- The IsString type alias uses a conditional type to check if a type T extends the string.
- If T is assignable to string, it resolves to 'Yes'; otherwise, it resolves to 'No'.
- Test1 is evaluated as 'Yes' because the string extends the string.
- Test2 is evaluated as 'No' because the number does not extend the string.
Output:
Test1: Yes
Test2: No
JavaScript
type Num<T> = T extends number[] ? number
: (T extends string[] ? string : never)
// Return num
const num: Num<number[]> = 4;
// Return invalid
const stringnum: Num<number> = "7";
console.log(num, stringnum);
Conditional Type Constraints
Conditional type constraints allow defining constraints on generic types within conditional types, enabling dynamic and precise type handling.
JavaScript
type CheckNum<T> = T extends number ? T : never;
type NumbersOnly<T extends any[]> = {
[K in keyof T]: CheckNum<T[K]>;
};
const num: NumbersOnly<[4, 5, 6, 8]> = [4, 5, 6, 8];
const invalid: NumbersOnly<[4, 6, "7"]> = [4, 6, "7"];
- CheckNum<T> ensures only numbers are retained; other types resolve to never.
- NumbersOnly<T> applies CheckNum to each array element, filtering non-numbers.
Output:
Type '"7"' is not assignable to type 'never'.
Inferring Within Conditional Types
This feature extracts and utilizes types within a conditional type definition, enabling precise transformations.
JavaScript
type ElementType<T> = T extends (infer U)[] ? U : never;
const numbers: number[] = [1, 2, 3];
const element: ElementType<typeof numbers> = numbers[0];
const invalidElement: ElementType<typeof numbers> = "string";
- ElementType<T> extracts element types from arrays using the infer keyword.
- element correctly resolves to number; assigning a string is invalid.
Output:
Type 'string' is not assignable to type 'number'.
Distributive Conditional Types
These types distribute over unions, applying conditional logic to each union member individually.
JavaScript
type Colors = 'red' | 'blue' | 'green';
type ColorClassMap = {
red: 'danger';
blue: 'primary';
green: 'success';
};
type MapColorsToClasses<T extends string> = T extends keyof ColorClassMap
? { [K in T]: ColorClassMap[T] }
: never;
const redClass: MapColorsToClasses<Colors> = { red: 'danger' };
const invalidClass: MapColorsToClasses<Colors> = { yellow: 'warning' };
- MapColorsToClasses<T> checks if T matches a key in ColorClassMap, mapping it accordingly.
- Invalid colors like 'yellow' are rejected because they do not exist in ColorClassMap.
Output:
Type '{ yellow: "warning"; }' is not assignable to type 'never'.
Best Practices of Using TypeScript Conditional Types
- Use conditional types to create flexible, reusable type definitions.
- Combine conditional types with generics for enhanced adaptability.
- Utilize the infer keyword for type inference in complex scenarios.
Similar Reads
Data types in TypeScript In TypeScript, a data type defines the kind of values a variable can hold, ensuring type safety and enhancing code clarity.Primitive Types: Basic types like number, string, boolean, null, undefined, and symbol.Object Types: Complex structures including arrays, classes, interfaces, and functions.Prim
3 min read
How to create conditional types in TypeScript ? Conditional types in TypeScript enable defining types based on conditions, similar to conditional statements in code. They determine different types of values, making functions adaptable to various input types, and enhancing code flexibility and maintainability. Syntax: We can create conditional typ
3 min read
TypeScript Constraints TypeScript constraints are used in generic type declarations to restrict the types that can be used as type arguments for the generic. Constraints allow you to specify that a generic type parameter must meet certain criteria, such as implementing a particular interface, having a specific method, or
2 min read
Type Manipulation in TypeScript TypeScript offers strong tools for types manipulation and transformation, these tools allow programmers to create new types by composing, intersecting, unionizing, mapping and conditioning existing ones, in this article we will investigate some of the advanced type-manipulation features in TypeScrip
3 min read
TypeScript Object Types TypeScript object types define the structure of objects by specifying property types, ensuring type safety and clarity when passing objects as function parameters.Optional properties, denoted with a ? provide flexibility for objects with varying properties. This approach enhances code robustness by
3 min read