Typescript conditional types
Created By: chatGPT
In TypeScript, conditional types enable you to create types based on conditions, making your code more flexible and reusable. A conditional type uses the syntax
A extends B ? C : D
, where if type A
is assignable to type B
, the type resolves to C
; otherwise, it resolves to D
.type IsString<T> = T extends string ? 'Yes' : 'No';
Here’s an example where we define a type
IsString
that checks if a given type T
is a string
. If it is a string
, it resolves to 'Yes', otherwise, it resolves to 'No'.type Check1 = IsString<string>; // 'Yes'
type Check2 = IsString<number>; // 'No'
You can also use conditional types with generic types to create more powerful constructs. For instance, you can infer types using the
infer
keyword within a conditional type.type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
In this example,
ReturnType
checks if T
is a function type. If so, it infers the return type R
; otherwise, it resolves to never
. This can be particularly useful when writing utility types.type Func = (x: number) => string;
type Test = ReturnType<Func>; // string
You can also use conditional types for mapping over keys. For instance, you could create a type that transforms all keys of an object type based on their type.
type Nullable<T> = { [K in keyof T]: T[K] | null };
The
Nullable
type takes an object type T
and constructs a new object type where all the properties are of types T[K] | null
. This way, each property can be either its original type or null
.type Example = { name: string; age: number; };
type NullableExample = Nullable<Example>;
// { name: string | null; age: number | null; }
Another interesting use case is using conditional types for extracting properties of specific types from an object type.
type FilterType<T, U> = {
[K in keyof T]-?: T[K] extends U ? K : never;
}[keyof T];
This
FilterType
utility type filters the keys of T
that have a type assignable to U
. The result is a union of the keys that satisfy the condition.type Person = { id: number; name: string; active: boolean; };
type StringKeys = FilterType<Person, string>; // 'name'