Distributive conditional typing is a powerful feature in TypeScript that allows for more flexible and expressive type definitions. It enables developers to create types that can adapt based on the structure of other types. This feature is particularly useful when working with union types, as it allows TypeScript to infer types based on the individual members of the union.
To understand how distributive conditional typing works, it’s essential to grasp the concept of conditional types in TypeScript. A conditional type selects one of two possible types based on a condition, which is expressed in the form of `A extends B ? C : D`. Here, if type `A` is assignable to type `B`, the type resolves to `C`; otherwise, it resolves to `D`.
When a conditional type is applied to a union type, TypeScript distributes the conditional type across each member of the union. This means that instead of evaluating the conditional type once for the entire union, TypeScript evaluates it for each member individually.
For example, consider the following code snippet:
type IsString = T extends string ? "Yes" : "No";
type Result1 = IsString; // "Yes" | "No"
In this example, `IsString` is a conditional type that checks if `T` extends `string`. When applied to the union type `string | number`, TypeScript evaluates the condition for each member of the union, resulting in the type `"Yes" | "No".`
Let’s look at a more practical example where we want to create a utility type that extracts the types of properties from an object based on their types:
type ExtractStringProperties = {
[K in keyof T]: T[K] extends string ? K : never
}[keyof T];
type Example = {
name: string;
age: number;
city: string;
};
type StringProperties = ExtractStringProperties; // "name" | "city"
Here, `ExtractStringProperties` is a mapped type that iterates over the keys of type `T`. For each key, it checks if the corresponding value is a string. If it is, it keeps the key; otherwise, it replaces it with `never`. The final result is a union of the keys that have string values.
In summary, distributive conditional typing is a fundamental concept in TypeScript that enhances type safety and flexibility. By understanding how it works and applying best practices, developers can create robust and maintainable codebases.