patterntypescriptModeratepending
TypeScript Conditional Types and infer Keyword
Viewed 0 times
conditional typesinfertype-level programmingReturnTypeAwaiteddistributive
Problem
Need to extract types from complex generic types, unwrap promises, get function return types, or build type-level logic that adapts based on input types.
Solution
Conditional types with infer:
// Basic conditional type
type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // true
type B = IsString<42>; // false
// Extract return type (built-in: ReturnType)
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Result = MyReturnType<() => string>; // string
// Unwrap Promise
type Awaited<T> = T extends Promise<infer U> ? Awaited<U> : T;
type X = Awaited<Promise<Promise<string>>>; // string
// Extract array element type
type ElementOf<T> = T extends (infer E)[] ? E : never;
type Item = ElementOf<string[]>; // string
// Extract specific property types
type PropType<T, K extends keyof T> = T[K];
// Distributive conditional types
type NonNullable<T> = T extends null | undefined ? never : T;
type C = NonNullable<string | null | undefined>; // string
// Practical: extract route params
type ExtractParams<T extends string> =
T extends `${string}:${infer Param}/${infer Rest}`
? { [K in Param | keyof ExtractParams<Rest>]: string }
: T extends `${string}:${infer Param}`
? { [K in Param]: string }
: {};
type Params = ExtractParams<'/users/:id/posts/:postId'>;
// { id: string; postId: string }Why
Conditional types enable type-level programming. With infer, you can extract and transform types from other types, creating powerful type utilities that catch errors at compile time.
Gotchas
- Conditional types distribute over unions by default - wrap in [T] extends [U] to prevent
- infer can only be used in the extends clause of conditional types
Context
Advanced TypeScript type programming
Revisions (0)
No revisions yet.