typescript type safety expert

TypeScript Type Safety Expert

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "typescript type safety expert" with this command: npx skills add krosebrook/source-of-truth-monorepo/krosebrook-source-of-truth-monorepo-typescript-type-safety-expert

TypeScript Type Safety Expert

Advanced TypeScript patterns for bulletproof type safety.

Advanced Type Patterns

Branded Types

// Prevent mixing incompatible types type Brand<K, T> = K & { __brand: T };

type UserId = Brand<string, 'UserId'>; type ProductId = Brand<string, 'ProductId'>;

const userId = 'user_123' as UserId; const productId = 'prod_456' as ProductId;

function getUser(id: UserId) { /* ... */ }

getUser(userId); // ✅ OK getUser(productId); // ❌ Type error!

Discriminated Unions

type Success<T> = { success: true; data: T }; type Error = { success: false; error: string }; type Result<T> = Success<T> | Error;

function handleResult<T>(result: Result<T>) { if (result.success) { // TypeScript knows result.data exists console.log(result.data); } else { // TypeScript knows result.error exists console.error(result.error); } }

Template Literal Types

type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; type Route = /${string}; type Endpoint = ${HttpMethod} ${Route};

const endpoint: Endpoint = 'GET /users'; // ✅ const invalid: Endpoint = 'FETCH /data'; // ❌ Type error

// Dynamic key generation type EventName = on${Capitalize&#x3C;string>}; const onClick: EventName = 'onClick'; // ✅ const invalid: EventName = 'click'; // ❌

Recursive Types

type JSONValue = | string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };

const validJSON: JSONValue = { name: "Alice", age: 30, tags: ["developer", "typescript"], metadata: { created: "2024-01-01", nested: { deep: true } } };

Utility Type Combinations

// Make all properties optional recursively type DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]; };

// Make specific keys required type RequireKeys<T, K extends keyof T> = T & Required<Pick<T, K>>;

// Exclude null and undefined type NonNullableKeys<T> = { [P in keyof T]: NonNullable<T[P]>; };

// Extract function parameters type Params<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

Type-Safe API Client

type API = { '/users': { GET: { response: User[] }; POST: { body: UserCreate; response: User }; }; '/users/:id': { GET: { params: { id: string }; response: User }; PUT: { params: { id: string }; body: UserUpdate; response: User }; DELETE: { params: { id: string }; response: void }; }; };

type ExtractParams<T extends string> = T extends ${infer _Start}:${infer Param}/${infer Rest} ? { [K in Param | keyof ExtractParams<Rest>]: string } : T extends ${infer _}:${infer Param} ? { [K in Param]: string } : {};

async function apiCall< Path extends keyof API, Method extends keyof API[Path]

( method: Method, path: Path, options?: API[Path][Method] extends { body: infer B } ? { body: B; params?: ExtractParams<Path> } : { params?: ExtractParams<Path> } ): Promise<API[Path][Method] extends { response: infer R } ? R : never> { // Implementation return {} as any; }

// Usage - fully type-safe! const user = await apiCall('GET', '/users/:id', { params: { id: '123' } // ✅ Required });

const newUser = await apiCall('POST', '/users', { body: { email: 'test@test.com', name: 'Test' } // ✅ Required });

Builder Pattern with Type State

class QueryBuilder<T extends Record<string, any>, HasWhere = false> { private whereClause?: string;

where<K extends keyof T>(key: K, value: T[K]): QueryBuilder<T, true> { this.whereClause = ${String(key)} = ${value}; return this as any; }

// execute() only available after where() is called execute(this: QueryBuilder<T, true>): Promise<T[]> { return Promise.resolve([]); } }

const query = new QueryBuilder<User>(); query.execute(); // ❌ Type error - must call where() first query.where('id', 123).execute(); // ✅ OK

Strict Event Emitter

type EventMap = { 'user:created': { id: string; name: string }; 'user:deleted': { id: string }; 'data:update': { data: any[] }; };

class TypedEventEmitter<T extends Record<string, any>> { private listeners: { [K in keyof T]?: Array<(data: T[K]) => void>; } = {};

on<K extends keyof T>(event: K, callback: (data: T[K]) => void) { if (!this.listeners[event]) { this.listeners[event] = []; } this.listeners[event]!.push(callback); }

emit<K extends keyof T>(event: K, data: T[K]) { this.listeners[event]?.forEach(cb => cb(data)); } }

const emitter = new TypedEventEmitter<EventMap>();

emitter.on('user:created', (data) => { console.log(data.id, data.name); // ✅ Fully typed });

emitter.emit('user:created', { id: '1', name: 'Alice' }); // ✅ OK emitter.emit('user:created', { wrong: 'data' }); // ❌ Type error

Zod Integration

import { z } from 'zod';

const UserSchema = z.object({ id: z.string().uuid(), email: z.string().email(), age: z.number().min(0).max(150), role: z.enum(['admin', 'user', 'guest']), metadata: z.record(z.unknown()).optional(), });

type User = z.infer<typeof UserSchema>;

// Runtime validation with compile-time types function validateUser(data: unknown): User { return UserSchema.parse(data); }

TSConfig Best Practices

{ "compilerOptions": { "strict": true, "exactOptionalPropertyTypes": true, "noUncheckedIndexedAccess": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noFallthroughCasesInSwitch": true, "allowUnusedLabels": false, "allowUnreachableCode": false, "forceConsistentCasingInFileNames": true, "skipLibCheck": true } }

Quick Patterns

// Const assertions const config = { apiUrl: 'https://api.example.com', timeout: 5000, } as const; // Type: { readonly apiUrl: "https://api.example.com"; readonly timeout: 5000 }

// Satisfies operator const colors = { red: [255, 0, 0], green: [0, 255, 0], } satisfies Record<string, [number, number, number]>;

// Index signatures with template literals type HTTPHeaders = { [K in x-${string}]: string; };

// Conditional types type IsArray<T> = T extends any[] ? true : false; type Test1 = IsArray<string[]>; // true type Test2 = IsArray<string>; // false

When to Use: Advanced TypeScript features, eliminating runtime errors, type-safe APIs, complex type systems.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

working-with-claude-code

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

receiving-code-review

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

requesting-code-review

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

finishing-a-development-branch

No summary provided by upstream source.

Repository SourceNeeds Review