TypeScript
Beginner
1 min read
Conditional Types and Infer
Example
// Basic conditional type
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
// Extract return type (mirrors built-in ReturnType)
type MyReturnType<T> = T extends (...args: unknown[]) => infer R ? R : never;
function fetchUser(): Promise<{ id: number; name: string }> {
return Promise.resolve({ id: 1, name: "Alice" });
}
type FetchResult = MyReturnType<typeof fetchUser>;
// Promise<{ id: number; name: string }>
// Unwrap a Promise
type Awaited2<T> = T extends Promise<infer U> ? Awaited2<U> : T;
type Resolved = Awaited2<Promise<Promise<number>>>; // number
// Element type of an array
type ElementType<T> = T extends (infer U)[] ? U : never;
type NumElem = ElementType<number[]>; // number
// Distributive conditional type
type NonNullable2<T> = T extends null | undefined ? never : T;
type Cleaned = NonNullable2<string | null | undefined | number>;
// string | number
// Exclude and Extract mirroring built-ins
type MyExclude<T, U> = T extends U ? never : T;
type MyExtract<T, U> = T extends U ? T : never;
type Animals = "cat" | "dog" | "fish" | "bird";
type Pets = MyExtract<Animals, "cat" | "dog">; // "cat" | "dog"
type Wild = MyExclude<Animals, "cat" | "dog">; // "fish" | "bird"
Related Resources
TypeScript Reference
Complete tag & property list
TypeScript How-To Guides
Step-by-step practical guides
TypeScript Exercises
Practice what you've learned
More in TypeScript