TypeScript Generics and Advanced Types
/ 4 min read
TypeScript Generics and Advanced Types
Table of Contents
Advanced Generics
Generic Constraints and Defaults
// Generic constraintsinterface HasLength { length: number;}
function measureLength<T extends HasLength>(item: T): number { return item.length;}
// Generic defaultsinterface ApiResponse<T = any> { data: T; status: number; message: string;}
// Generic factoryclass GenericFactory<T> { create<K extends keyof T>(property: K, value: T[K]): T { return { [property]: value } as T; }}Generic Type Inference
// Infer return typesfunction wrap<T>(value: T): [T] { return [value];}
// Infer complex typestype UnwrapPromise<T> = T extends Promise<infer U> ? U : T;type UnwrapArray<T> = T extends Array<infer U> ? U : T;
// Generic type guardsfunction isOfType<T>(value: unknown, property: keyof T): value is T { return value != null && property in value;}Conditional Types
Basic Conditional Types
type IsString<T> = T extends string ? true : false;type IsStringType = IsString<string>; // truetype IsNumberType = IsString<number>; // false
// Conditional type with unionstype NonNullable<T> = T extends null | undefined ? never : T;
// Distributive conditional typestype ToArray<T> = T extends any ? T[] : never;type StringOrNumberArray = ToArray<string | number>; // string[] | number[]Advanced Conditional Types
// Extract and Excludetype Extract<T, U> = T extends U ? T : never;type Exclude<T, U> = T extends U ? never : T;
// Type inference in conditional typestype ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;type Parameters<T> = T extends (...args: infer P) => any ? P : never;
// Recursive conditional typestype DeepReadonly<T> = { readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];};Mapped Types
Basic Mapped Types
// Make all properties optionaltype Partial<T> = { [P in keyof T]?: T[P];};
// Make all properties readonlytype Readonly<T> = { readonly [P in keyof T]: T[P];};
// Make all properties nullabletype Nullable<T> = { [P in keyof T]: T[P] | null;};Advanced Mapped Types
// Mapped type with key remappingtype Getters<T> = { [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P];};
// Filtered mapped typestype PickByType<T, ValueType> = { [P in keyof T as T[P] extends ValueType ? P : never]: T[P];};
// Deep mapped typestype DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];};Template Literal Types
Basic Template Literals
type EventName = 'click' | 'focus' | 'blur';type EventHandler = `on${Capitalize<EventName>}`; // 'onClick' | 'onFocus' | 'onBlur'
// Combining with other typestype PropName = 'first' | 'last';type FullProp = `${PropName}Name`; // 'firstName' | 'lastName'Advanced Template Literals
// Complex string manipulationtype CamelToSnake<S extends string> = S extends `${infer T}${infer U}` ? `${T extends Capitalize<T> ? '_${Lowercase<T>}' : T}${CamelToSnake<U>}` : S;
// URL pattern matchingtype HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';type Endpoint = '/users' | '/posts' | '/comments';type ApiRoute = `${HttpMethod} ${Endpoint}`;Utility Types
Built-in Utility Types
// Pick and Omittype User = { id: number; name: string; email: string; password: string;};
type PublicUser = Omit<User, 'password'>;type Credentials = Pick<User, 'email' | 'password'>;
// Record and Excludetype PageInfo = { title: string; path: string;};
type SiteMap = Record<string, PageInfo>;Custom Utility Types
// DeepRequired - Make all properties required recursivelytype DeepRequired<T> = { [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];};
// Mutable - Remove readonly modifiertype Mutable<T> = { -readonly [P in keyof T]: T[P];};
// FunctionProperties - Extract function propertiestype FunctionProperties<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P];};Practical Examples
// API Response Handlertype ApiResponse<T> = { data: T; status: number; error?: string;};
type ApiEndpoints = { '/users': User[]; '/posts': Post[]; '/comments': Comment[];};
type ApiClient = { [P in keyof ApiEndpoints as `fetch${Capitalize<string & P>}`]: () => Promise<ApiResponse<ApiEndpoints[P]>>;};
// Form Validationtype ValidationRule<T> = { validate: (value: T) => boolean; message: string;};
type FormValidation<T> = { [P in keyof T]: ValidationRule<T[P]>[];};
// Event Systemtype EventMap = { click: MouseEvent; keypress: KeyboardEvent; focus: FocusEvent;};
type EventHandlers = { [E in keyof EventMap as `on${Capitalize<string & E>}`]: (event: EventMap[E]) => void;};These advanced TypeScript features enable you to write more type-safe and maintainable code. They’re particularly useful when:
- Building reusable components and libraries
- Creating type-safe APIs
- Implementing complex validation logic
- Handling data transformations
- Building event systems
Would you like me to:
- Add more examples for any specific section?
- Create additional posts about other TypeScript topics?
- Add more practical use cases?