name: typescript description: This skill should be used when working with TypeScript code, including type definitions, type inference, generics, utility types, and TypeScript configuration. Provides comprehensive knowledge of TypeScript patterns, best practices, and advanced type system features.
This skill provides comprehensive knowledge and patterns for working with TypeScript effectively in modern applications.
Use this skill when:
TypeScript provides static typing for JavaScript with a powerful type system that includes:
Leverage TypeScript's type inference to write less verbose code:
as const for immutable literal typesImplement type-safe patterns:
When designing APIs, follow these patterns:
Interface vs Type Alias:
interface for object shapes that may be extendedtype for unions, intersections, and complex type operationstype with mapped types and conditional typesGeneric Constraints:
// Use extends for generic constraints
function getValue<T extends { id: string }>(item: T): string {
return item.id
}
Discriminated Unions:
// Use for type-safe state machines
type State =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: Data }
| { status: 'error'; error: Error }
Use built-in utility types for common transformations:
Partial<T> - Make all properties optionalRequired<T> - Make all properties requiredReadonly<T> - Make all properties readonlyPick<T, K> - Select specific propertiesOmit<T, K> - Exclude specific propertiesRecord<K, T> - Create object type with specific keysExclude<T, U> - Exclude types from unionExtract<T, U> - Extract types from unionNonNullable<T> - Remove null/undefinedReturnType<T> - Get function return typeParameters<T> - Get function parameter typesAwaited<T> - Unwrap Promise typeMapped Types:
// Transform object types
type Nullable<T> = {
[K in keyof T]: T[K] | null
}
type ReadonlyDeep<T> = {
readonly [K in keyof T]: T[K] extends object
? ReadonlyDeep<T[K]>
: T[K]
}
Conditional Types:
// Type-level logic
type IsArray<T> = T extends Array<any> ? true : false
type Flatten<T> = T extends Array<infer U> ? U : T
Template Literal Types:
// String manipulation at type level
type EventName<T extends string> = `on${Capitalize<T>}`
type Route = `/api/${'users' | 'posts'}/${string}`
Use type guards and narrowing techniques:
typeof guards:
if (typeof value === 'string') {
// value is string here
}
instanceof guards:
if (error instanceof Error) {
// error is Error here
}
Custom type guards:
function isUser(value: unknown): value is User {
return typeof value === 'object' && value !== null && 'id' in value
}
Discriminated unions:
function handle(state: State) {
switch (state.status) {
case 'idle':
// state is { status: 'idle' }
break
case 'success':
// state is { status: 'success'; data: Data }
console.log(state.data)
break
}
}
Typing Third-Party Libraries:
npm install --save-dev @types/package-name.d.ts files when types unavailableDeclaration Files:
// globals.d.ts
declare global {
interface Window {
myCustomProperty: string
}
}
export {}
Configure tsconfig.json for strict type checking:
Essential Strict Options:
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true
}
}
Let TypeScript infer types when they're obvious from context.
Enable strict type checking to catch more errors at compile time.
any TypeUse unknown for truly unknown types, then narrow with type guards.
Use as const for immutable values and narrow literal types.
Use for state machines and variant types for better type safety.
Extract common type patterns into reusable generics.
Create distinct types for values with same structure but different meaning.
Add JSDoc comments to explain non-obvious type decisions.
Use import type for type-only imports to aid tree-shaking.
Use type guards to safely work with error objects.
// Use interface for component props
interface ButtonProps {
variant?: 'primary' | 'secondary'
size?: 'sm' | 'md' | 'lg'
onClick?: () => void
children: React.ReactNode
}
export function Button({ variant = 'primary', size = 'md', onClick, children }: ButtonProps) {
// implementation
}
// Use discriminated unions for API responses
type ApiResponse<T> =
| { success: true; data: T }
| { success: false; error: string }
// Helper for safe API calls
async function fetchData<T>(url: string): Promise<ApiResponse<T>> {
try {
const response = await fetch(url)
const data = await response.json()
return { success: true, data }
} catch (error) {
return { success: false, error: String(error) }
}
}
// Use interfaces for state objects
interface AppState {
user: User | null
isAuthenticated: boolean
theme: 'light' | 'dark'
}
// Use type for actions (discriminated union)
type AppAction =
| { type: 'LOGIN'; payload: User }
| { type: 'LOGOUT' }
| { type: 'SET_THEME'; payload: 'light' | 'dark' }
For detailed information on specific topics, refer to:
references/type-system.md - Deep dive into TypeScript's type systemreferences/utility-types.md - Complete guide to built-in utility typesreferences/advanced-types.md - Advanced type patterns and techniquesreferences/tsconfig-reference.md - Comprehensive tsconfig.json referencereferences/common-patterns.md - Common TypeScript patterns and idiomsexamples/ - Practical code examplesType 'X' is not assignable to type 'Y':
Object is possibly 'null' or 'undefined':
object?.propertyvalue ?? defaultValueType 'any' implicitly has...
unknown instead of any when appropriateCannot find module or its type declarations:
@types/package-name.d.ts declaration filetypes array in tsconfig.jsonUse TypeScript with React 19 features:
React.FC sparingly (prefer explicit typing)Type TanStack libraries properly:
Combine Zod with TypeScript:
z.infer<typeof schema> to extract types from schemasThe TypeScript documentation provides comprehensive information: