Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Part of a 72-plugin marketplace with 112 AI agents and 146 skills for Claude Code development automation.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: typescript-advanced-types3description: Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications. Use when implementing complex type logic, creating reusable type utilities, or ensuring compile-time type safety in TypeScript projects.4---56# TypeScript Advanced Types78Comprehensive guidance for mastering TypeScript's advanced type system including generics, conditional types, mapped types, template literal types, and utility types for building robust, type-safe applications.910## When to Use This Skill1112- Building type-safe libraries or frameworks13- Creating reusable generic components14- Implementing complex type inference logic15- Designing type-safe API clients16- Building form validation systems17- Creating strongly-typed configuration objects18- Implementing type-safe state management19- Migrating JavaScript codebases to TypeScript2021## Core Concepts2223### 1. Generics2425**Purpose:** Create reusable, type-flexible components while maintaining type safety.2627**Basic Generic Function:**2829```typescript30function identity<T>(value: T): T {31return value;32}3334const num = identity<number>(42); // Type: number35const str = identity<string>("hello"); // Type: string36const auto = identity(true); // Type inferred: boolean37```3839**Generic Constraints:**4041```typescript42interface HasLength {43length: number;44}4546function logLength<T extends HasLength>(item: T): T {47console.log(item.length);48return item;49}5051logLength("hello"); // OK: string has length52logLength([1, 2, 3]); // OK: array has length53logLength({ length: 10 }); // OK: object has length54// logLength(42); // Error: number has no length55```5657**Multiple Type Parameters:**5859```typescript60function merge<T, U>(obj1: T, obj2: U): T & U {61return { ...obj1, ...obj2 };62}6364const merged = merge({ name: "John" }, { age: 30 });65// Type: { name: string } & { age: number }66```6768### 2. Conditional Types6970**Purpose:** Create types that depend on conditions, enabling sophisticated type logic.7172**Basic Conditional Type:**7374```typescript75type IsString<T> = T extends string ? true : false;7677type A = IsString<string>; // true78type B = IsString<number>; // false79```8081**Extracting Return Types:**8283```typescript84type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;8586function getUser() {87return { id: 1, name: "John" };88}8990type User = ReturnType<typeof getUser>;91// Type: { id: number; name: string; }92```9394**Distributive Conditional Types:**9596```typescript97type ToArray<T> = T extends any ? T[] : never;9899type StrOrNumArray = ToArray<string | number>;100// Type: string[] | number[]101```102103**Nested Conditions:**104105```typescript106type TypeName<T> = T extends string107? "string"108: T extends number109? "number"110: T extends boolean111? "boolean"112: T extends undefined113? "undefined"114: T extends Function115? "function"116: "object";117118type T1 = TypeName<string>; // "string"119type T2 = TypeName<() => void>; // "function"120```121122### 3. Mapped Types123124**Purpose:** Transform existing types by iterating over their properties.125126**Basic Mapped Type:**127128```typescript129type Readonly<T> = {130readonly [P in keyof T]: T[P];131};132133interface User {134id: number;135name: string;136}137138type ReadonlyUser = Readonly<User>;139// Type: { readonly id: number; readonly name: string; }140```141142**Optional Properties:**143144```typescript145type Partial<T> = {146[P in keyof T]?: T[P];147};148149type PartialUser = Partial<User>;150// Type: { id?: number; name?: string; }151```152153**Key Remapping:**154155```typescript156type Getters<T> = {157[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];158};159160interface Person {161name: string;162age: number;163}164165type PersonGetters = Getters<Person>;166// Type: { getName: () => string; getAge: () => number; }167```168169**Filtering Properties:**170171```typescript172type PickByType<T, U> = {173[K in keyof T as T[K] extends U ? K : never]: T[K];174};175176interface Mixed {177id: number;178name: string;179age: number;180active: boolean;181}182183type OnlyNumbers = PickByType<Mixed, number>;184// Type: { id: number; age: number; }185```186187### 4. Template Literal Types188189**Purpose:** Create string-based types with pattern matching and transformation.190191**Basic Template Literal:**192193```typescript194type EventName = "click" | "focus" | "blur";195type EventHandler = `on${Capitalize<EventName>}`;196// Type: "onClick" | "onFocus" | "onBlur"197```198199**String Manipulation:**200201```typescript202type UppercaseGreeting = Uppercase<"hello">; // "HELLO"203type LowercaseGreeting = Lowercase<"HELLO">; // "hello"204type CapitalizedName = Capitalize<"john">; // "John"205type UncapitalizedName = Uncapitalize<"John">; // "john"206```207208**Path Building:**209210```typescript211type Path<T> = T extends object212? {213[K in keyof T]: K extends string ? `${K}` | `${K}.${Path<T[K]>}` : never;214}[keyof T]215: never;216217interface Config {218server: {219host: string;220port: number;221};222database: {223url: string;224};225}226227type ConfigPath = Path<Config>;228// Type: "server" | "database" | "server.host" | "server.port" | "database.url"229```230231### 5. Utility Types232233**Built-in Utility Types:**234235```typescript236// Partial<T> - Make all properties optional237type PartialUser = Partial<User>;238239// Required<T> - Make all properties required240type RequiredUser = Required<PartialUser>;241242// Readonly<T> - Make all properties readonly243type ReadonlyUser = Readonly<User>;244245// Pick<T, K> - Select specific properties246type UserName = Pick<User, "name" | "email">;247248// Omit<T, K> - Remove specific properties249type UserWithoutPassword = Omit<User, "password">;250251// Exclude<T, U> - Exclude types from union252type T1 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"253254// Extract<T, U> - Extract types from union255type T2 = Extract<"a" | "b" | "c", "a" | "b">; // "a" | "b"256257// NonNullable<T> - Exclude null and undefined258type T3 = NonNullable<string | null | undefined>; // string259260// Record<K, T> - Create object type with keys K and values T261type PageInfo = Record<"home" | "about", { title: string }>;262```263264## Detailed worked examples and patterns265266Detailed sections (starting with `## Advanced Patterns`) live in `references/details.md`. Read that file when the navigation summary above is insufficient.267268## Best Practices2692701. **Use `unknown` over `any`**: Enforce type checking2712. **Prefer `interface` for object shapes**: Better error messages2723. **Use `type` for unions and complex types**: More flexible2734. **Leverage type inference**: Let TypeScript infer when possible2745. **Create helper types**: Build reusable type utilities2756. **Use const assertions**: Preserve literal types2767. **Avoid type assertions**: Use type guards instead2778. **Document complex types**: Add JSDoc comments2789. **Use strict mode**: Enable all strict compiler options27910. **Test your types**: Use type tests to verify type behavior280281## Type Testing282283```typescript284// Type assertion tests285type AssertEqual<T, U> = [T] extends [U]286? [U] extends [T]287? true288: false289: false;290291type Test1 = AssertEqual<string, string>; // true292type Test2 = AssertEqual<string, number>; // false293type Test3 = AssertEqual<string | number, string>; // false294295// Expect error helper296type ExpectError<T extends never> = T;297298// Example usage299type ShouldError = ExpectError<AssertEqual<string, number>>;300```301302## Common Pitfalls3033041. **Over-using `any`**: Defeats the purpose of TypeScript3052. **Ignoring strict null checks**: Can lead to runtime errors3063. **Too complex types**: Can slow down compilation3074. **Not using discriminated unions**: Misses type narrowing opportunities3085. **Forgetting readonly modifiers**: Allows unintended mutations3096. **Circular type references**: Can cause compiler errors3107. **Not handling edge cases**: Like empty arrays or null values311312## Performance Considerations313314- Avoid deeply nested conditional types315- Use simple types when possible316- Cache complex type computations317- Limit recursion depth in recursive types318- Use build tools to skip type checking in production319