In TypeScript, conditional types are a powerful feature that enables types to be determined based on a condition. Their syntax resembles the ternary operator in JavaScript (condition ? trueType : falseType). Conditional types are particularly valuable in generic programming, offering a flexible approach to select between two possible types depending on the relationship between types.
Syntax
The basic syntax of conditional types is as follows:
typescriptT extends U ? X : Y
Here, type T is checked for compatibility with type U (i.e., whether T can be assigned to U). If compatible, the result is X; otherwise, it is Y.
Example
Suppose we want to define a type that returns different types based on whether the input is an array or not. If it is an array type, we return the element type of the array; otherwise, we return the original type.
typescripttype ElementType<T> = T extends Array<infer U> ? U : T; // Usage example type numArray = ElementType<number[]>; // Type is number type str = ElementType<string>; // Type is string
In the above example, ElementType<T> is a conditional type that checks whether T can be assigned to Array<infer U>. If T is an array type, such as number[], then U is inferred as the element type of the array (in this case, number), and the conditional type returns U. If T is not an array, it directly returns T.
Use Cases
Conditional types are ideal for deriving types based on conditions within the type system, which is highly useful when handling diverse data types. They are commonly employed in library type definitions to provide more precise type support and type safety.
For example, we can use conditional types to implement a type-safe function for retrieving object properties, which returns the corresponding property type based on the input key and object:
typescripttype PropertyType<T, K extends keyof T> = K extends keyof T ? T[K] : never; function getProperty<T, K extends keyof T>(obj: T, key: K): PropertyType<T, K> { return obj[key]; } const obj = { name: "Alice", age: 25 }; const name: string = getProperty(obj, 'name'); // Correct, returns type string const age: number = getProperty(obj, 'age'); // Correct, returns type number
In this example, PropertyType<T, K> is a conditional type that checks whether K is indeed a key of T; if so, it returns the type associated with that key.
Conditional types are a very powerful and flexible feature of the TypeScript type system, significantly enhancing its expressiveness and type safety.