Skill: typescript
Scope
- •Applies to: TypeScript v5+ advanced type system features, type-safe APIs, complex domain models, sophisticated type inference, compile-time guarantees
- •Does NOT cover: Basic TypeScript syntax, framework-specific patterns, runtime validation libraries (use Zod separately)
Assumptions
- •TypeScript v5+
- •Strict mode enabled (
"strict": trueintsconfig.json) - •Target: ES2020+ or higher
Principles
- •Use conditional types for type selection based on conditions
- •Use mapped types for systematic object type transformations
- •Use type guards (
value is Type) for runtime checking with type narrowing - •Use discriminated unions for type-safe state machines with exhaustiveness checking
- •Use branded types to prevent primitive mixing
- •Prefer
unknownoveranyfor type safety - •Use type guards over type assertions (
as Type) - •Keep types composable and shallow (avoid deep nesting)
- •Mark immutable data structures as
readonly
Constraints
MUST
- •Enable strict mode (
"strict": trueintsconfig.json) - •Use
unknowninstead ofanyfor untyped values - •Use type guards (
value is Type) instead of type assertions when possible
SHOULD
- •Use
typefor unions/utilities,interfacefor object shapes - •Keep types composable and shallow
- •Mark immutable data structures as
readonly - •Use branded types to prevent primitive mixing
AVOID
- •Using
any(useunknownwith type guards) - •Type assertions without validation
- •Overusing generics (only when types truly vary)
- •Deep type nesting (slow compilation, hard to debug)
Interactions
- •Works with zod for runtime validation with type inference
- •Complements nextjs for type-safe API routes
- •Complements fastify for type-safe route schemas
Patterns
Mapped Types
Transform object types systematically:
typescript
type Partial<T> = { [P in keyof T]?: T[P] }
type Readonly<T> = { readonly [P in keyof T]: T[P] }
type Pick<T, K extends keyof T> = { [P in K]: T[P] }
Type Guards
Runtime type checking with type narrowing:
typescript
function isString(value: unknown): value is string {
return typeof value === 'string'
}
function isSuccess(result: Result): result is Success {
return result.status === 'success'
}
Branded Types
Create nominal types for type safety:
typescript
type UserId = string & { readonly __brand: 'UserId' }
type PostId = string & { readonly __brand: 'PostId' }
function createUserId(id: string): UserId {
return id as UserId
}
Discriminated Unions
Type-safe state machines with exhaustiveness checking:
typescript
type LoadingState =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: string[] }
| { status: 'error'; error: Error }
References
- •Conditional Types - Type selection based on conditions
- •Advanced Generics - Generic constraints and inference patterns
- •Discriminated Unions - Type-safe state machines
Resources
- •TypeScript Handbook
- •Type Challenges
- •ts-toolbelt - Advanced type utilities library