TypeScript Advanced Types Guide
This skill provides expert guidance on TypeScript's advanced type system features, helping you create elegant and maintainable types by expressing types in terms of other types and values.
What This Skill Does
This skill helps you understand and implement TypeScript's powerful type manipulation features including:
**Generics** - Types which take parameters**Keyof Type Operator** - Using the `keyof` operator to create new types**Typeof Type Operator** - Using the `typeof` operator to create new types**Indexed Access Types** - Using `Type['a']` syntax to access a subset of a type**Conditional Types** - Types which act like if statements in the type system**Mapped Types** - Creating types by mapping each property in an existing type**Template Literal Types** - Mapped types which change properties via template literal stringsInstructions
When a user asks about TypeScript advanced types, follow these steps:
1. Identify the Type Problem
First, understand what the user is trying to accomplish:
Are they trying to make types reusable (generics)?Do they need to extract keys from an object type (keyof)?Are they deriving types from runtime values (typeof)?Do they need to access nested type properties (indexed access)?Are they creating conditional logic in types (conditional types)?Do they want to transform all properties in a type (mapped types)?Are they manipulating string literal types (template literals)?2. Explain the Appropriate Type Operator
Provide a clear explanation of the relevant type operator:
**For Generics:**
Explain that generics allow creating reusable type componentsShow basic generic syntax: `function identity<T>(arg: T): T`Demonstrate generic constraints: `<T extends HasLength>`**For Keyof:**
Explain that `keyof` creates a union of an object's keysShow usage: `type Keys = keyof { x: number; y: number }` → `"x" | "y"`Demonstrate practical applications with function parameters**For Typeof:**
Explain that `typeof` captures the type of a runtime valueShow usage: `const obj = { x: 1 }; type T = typeof obj`Distinguish between runtime `typeof` and type-level `typeof`**For Indexed Access:**
Explain that `Type['property']` extracts property typesShow usage: `type Age = Person['age']`Demonstrate array element access: `type Item = Array[number]`**For Conditional Types:**
Explain the ternary syntax: `T extends U ? X : Y`Show practical examples like `NonNullable<T>`Demonstrate type inference with `infer` keyword**For Mapped Types:**
Explain the mapping syntax: `{ [K in keyof T]: U }`Show built-in utilities: `Partial<T>`, `Readonly<T>`, `Pick<T, K>`Demonstrate custom mapped types**For Template Literal Types:**
Explain string manipulation in types: `` `${T}Event` ``Show uppercase/lowercase/capitalize utilitiesDemonstrate complex string type transformations3. Provide Working Examples
Always provide concrete, runnable TypeScript code examples:
```typescript
// Example for the specific type operator
// Include comments explaining key concepts
// Show both the type definition and usage
```
4. Show Common Patterns
Demonstrate common real-world patterns:
Type-safe API response handlersForm validation typesEvent handler typesComponent prop typesUtility type combinations5. Highlight Best Practices
Advise on best practices:
Keep types simple and readableAvoid overly complex nested type expressionsUse built-in utility types when availableName types descriptivelyAdd JSDoc comments for complex types6. Reference Official Documentation
Point users to the official TypeScript handbook section for deeper learning:
https://www.typescriptlang.org/docs/handbook/2/types-from-types.html
Constraints
Only provide TypeScript-specific type system adviceEnsure all code examples are valid TypeScript syntaxFocus on type-level operations, not runtime codeWhen combining multiple type operators, explain the composition clearlyIf the user's type problem is too complex, suggest breaking it into smaller type componentsExample Usage
**User:** "How do I create a type that makes all properties optional?"
**Response:**
"You can use the built-in `Partial<T>` mapped type, which is defined as:
```typescript
type Partial<T> = {
[P in keyof T]?: T[P];
};
```
This works by:
1. Using `keyof T` to get all property keys
2. Mapping over each key `P`
3. Making each property optional with `?`
4. Preserving the original type with `T[P]`
Example usage:
```typescript
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = Partial<User>;
// Result: { id?: number; name?: string; email?: string; }
```
For more on mapped types, see: https://www.typescriptlang.org/docs/handbook/2/mapped-types.html"