javascript-typescript

JavaScript & TypeScript

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 "javascript-typescript" with this command: npx skills add miles990/claude-software-skills/miles990-claude-software-skills-javascript-typescript

JavaScript & TypeScript

Overview

Modern JavaScript (ES6+) and TypeScript patterns for building robust applications.

TypeScript Fundamentals

Type Definitions

// Basic types type UserId = string; type Timestamp = number;

// Object types interface User { id: UserId; email: string; name: string; createdAt: Timestamp; metadata?: Record<string, unknown>; }

// Union types type Status = 'pending' | 'active' | 'inactive';

// Discriminated unions type Result<T, E = Error> = | { success: true; data: T } | { success: false; error: E };

// Generic types interface Repository<T extends { id: string }> { find(id: string): Promise<T | null>; findAll(filter?: Partial<T>): Promise<T[]>; create(data: Omit<T, 'id'>): Promise<T>; update(id: string, data: Partial<T>): Promise<T>; delete(id: string): Promise<void>; }

// Utility types type CreateUserInput = Omit<User, 'id' | 'createdAt'>; type UpdateUserInput = Partial<Pick<User, 'name' | 'metadata'>>; type UserKeys = keyof User;

// Conditional types type Nullable<T> = T | null; type NonNullableFields<T> = { [K in keyof T]-?: NonNullable<T[K]>; };

// Template literal types type EventName = on${Capitalize&#x3C;string>}; type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; type ApiRoute = /${string};

Type Guards

// Type predicates function isUser(obj: unknown): obj is User { return ( typeof obj === 'object' && obj !== null && 'id' in obj && 'email' in obj && typeof (obj as User).id === 'string' ); }

// Discriminated union guards interface Dog { kind: 'dog'; bark(): void; }

interface Cat { kind: 'cat'; meow(): void; }

type Animal = Dog | Cat;

function handleAnimal(animal: Animal) { switch (animal.kind) { case 'dog': animal.bark(); // TypeScript knows this is Dog break; case 'cat': animal.meow(); // TypeScript knows this is Cat break; } }

// Assertion functions function assertIsString(value: unknown): asserts value is string { if (typeof value !== 'string') { throw new Error('Value must be a string'); } }

// Exhaustive checks function assertNever(x: never): never { throw new Error(Unexpected value: ${x}); }

Async Patterns

Promises and Async/Await

// Promise creation function delay(ms: number): Promise<void> { return new Promise((resolve) => setTimeout(resolve, ms)); }

// Async/await with error handling async function fetchUser(id: string): Promise<Result<User>> { try { const response = await fetch(/api/users/${id});

if (!response.ok) {
  return {
    success: false,
    error: new Error(`HTTP ${response.status}`),
  };
}

const data = await response.json();
return { success: true, data };

} catch (error) { return { success: false, error: error instanceof Error ? error : new Error(String(error)), }; } }

// Parallel execution async function fetchAllUsers(ids: string[]): Promise<User[]> { const results = await Promise.all(ids.map((id) => fetchUser(id)));

return results .filter((r): r is { success: true; data: User } => r.success) .map((r) => r.data); }

// Promise.allSettled for partial failures async function fetchUsersSettled(ids: string[]) { const results = await Promise.allSettled( ids.map((id) => fetch(/api/users/${id}).then((r) => r.json())) );

return results.map((result, index) => ({ id: ids[index], status: result.status, value: result.status === 'fulfilled' ? result.value : null, error: result.status === 'rejected' ? result.reason : null, })); }

// Sequential execution with reduce async function processSequentially<T, R>( items: T[], processor: (item: T) => Promise<R> ): Promise<R[]> { return items.reduce(async (accPromise, item) => { const acc = await accPromise; const result = await processor(item); return [...acc, result]; }, Promise.resolve([] as R[])); }

Async Iterators

// Async generator async function* paginate<T>( fetcher: (page: number) => Promise<{ data: T[]; hasMore: boolean }> ): AsyncGenerator<T[], void, unknown> { let page = 1; let hasMore = true;

while (hasMore) { const result = await fetcher(page); yield result.data; hasMore = result.hasMore; page++; } }

// Using async iterator async function getAllItems() { const items: Item[] = [];

for await (const batch of paginate(fetchPage)) { items.push(...batch); }

return items; }

// Async iterator utilities async function* map<T, R>( iterable: AsyncIterable<T>, fn: (item: T) => R | Promise<R> ): AsyncGenerator<R> { for await (const item of iterable) { yield await fn(item); } }

async function* filter<T>( iterable: AsyncIterable<T>, predicate: (item: T) => boolean | Promise<boolean> ): AsyncGenerator<T> { for await (const item of iterable) { if (await predicate(item)) { yield item; } } }

async function* take<T>( iterable: AsyncIterable<T>, count: number ): AsyncGenerator<T> { let taken = 0; for await (const item of iterable) { if (taken >= count) break; yield item; taken++; } }

Functional Patterns

Higher-Order Functions

// Currying const add = (a: number) => (b: number) => a + b; const add5 = add(5); console.log(add5(3)); // 8

// Pipe and compose const pipe = <T>(...fns: Array<(arg: T) => T>) => (value: T): T => fns.reduce((acc, fn) => fn(acc), value);

const compose = <T>(...fns: Array<(arg: T) => T>) => (value: T): T => fns.reduceRight((acc, fn) => fn(acc), value);

// Usage const processString = pipe( (s: string) => s.trim(), (s: string) => s.toLowerCase(), (s: string) => s.replace(/\s+/g, '-') );

// Memoization function memoize<Args extends unknown[], Result>( fn: (...args: Args) => Result ): (...args: Args) => Result { const cache = new Map<string, Result>();

return (...args: Args): Result => { const key = JSON.stringify(args);

if (cache.has(key)) {
  return cache.get(key)!;
}

const result = fn(...args);
cache.set(key, result);
return result;

}; }

// Debounce function debounce<T extends (...args: any[]) => any>( fn: T, delay: number ): (...args: Parameters<T>) => void { let timeoutId: ReturnType<typeof setTimeout>;

return (...args: Parameters<T>) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => fn(...args), delay); }; }

// Throttle function throttle<T extends (...args: any[]) => any>( fn: T, limit: number ): (...args: Parameters<T>) => void { let inThrottle = false;

return (...args: Parameters<T>) => { if (!inThrottle) { fn(...args); inThrottle = true; setTimeout(() => (inThrottle = false), limit); } }; }

Immutable Data Patterns

// Object updates const updateUser = (user: User, updates: Partial<User>): User => ({ ...user, ...updates, });

// Nested updates interface State { users: Record<string, User>; settings: { theme: string; notifications: boolean; }; }

const updateNestedState = ( state: State, userId: string, userUpdate: Partial<User> ): State => ({ ...state, users: { ...state.users, [userId]: { ...state.users[userId], ...userUpdate, }, }, });

// Array operations (immutable) const addItem = <T>(arr: T[], item: T): T[] => [...arr, item]; const removeItem = <T>(arr: T[], index: number): T[] => [ ...arr.slice(0, index), ...arr.slice(index + 1), ]; const updateItem = <T>(arr: T[], index: number, item: T): T[] => [ ...arr.slice(0, index), item, ...arr.slice(index + 1), ];

Modern JavaScript Features

Destructuring and Spread

// Object destructuring with defaults and rename const { name, email, role = 'user', id: odentifier } = user;

// Nested destructuring const { address: { city, country }, } = user;

// Array destructuring const [first, second, ...rest] = items; const [, , third] = items; // Skip elements

// Function parameter destructuring function createUser({ name, email, role = 'user', }: { name: string; email: string; role?: string; }) { return { id: generateId(), name, email, role }; }

// Spread for merging const merged = { ...defaults, ...overrides }; const combined = [...arr1, ...arr2];

Optional Chaining and Nullish Coalescing

// Optional chaining const city = user?.address?.city; const firstItem = items?.[0]; const result = callback?.();

// Nullish coalescing (only null/undefined) const value = input ?? defaultValue;

// Combining them const displayName = user?.profile?.displayName ?? user?.name ?? 'Anonymous';

// Logical assignment operators let config = { timeout: 0 }; config.timeout ||= 5000; // Assigns if falsy (won't assign, 0 is falsy) config.timeout ??= 5000; // Assigns if null/undefined (won't assign) config.retries ??= 3; // Assigns (undefined)

Error Handling

// Custom error classes class AppError extends Error { constructor( message: string, public code: string, public statusCode: number = 500 ) { super(message); this.name = 'AppError'; Error.captureStackTrace(this, this.constructor); } }

class ValidationError extends AppError { constructor( message: string, public fields: Record<string, string[]> ) { super(message, 'VALIDATION_ERROR', 400); this.name = 'ValidationError'; } }

// Result type pattern (no exceptions) type Result<T, E = Error> = | { ok: true; value: T } | { ok: false; error: E };

function ok<T>(value: T): Result<T, never> { return { ok: true, value }; }

function err<E>(error: E): Result<never, E> { return { ok: false, error }; }

// Using Result function parseJSON<T>(json: string): Result<T, SyntaxError> { try { return ok(JSON.parse(json)); } catch (e) { return err(e as SyntaxError); } }

// Chaining Results function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> { return result.ok ? ok(fn(result.value)) : result; }

function flatMap<T, U, E>( result: Result<T, E>, fn: (value: T) => Result<U, E> ): Result<U, E> { return result.ok ? fn(result.value) : result; }

Module Patterns

// Named exports export const API_URL = 'https://api.example.com'; export function fetchData() {} export class ApiClient {}

// Default export export default class Logger {}

// Re-exports export { UserService } from './user-service'; export { default as Logger } from './logger'; export * from './types'; export * as utils from './utils';

// Dynamic imports async function loadModule() { const { default: Chart } = await import('./chart'); return new Chart(); }

// Conditional imports const adapter = await import( process.env.NODE_ENV === 'test' ? './mock-adapter' : './real-adapter' );

Related Skills

  • [[frontend]] - React/Next.js development

  • [[backend]] - Node.js server development

  • [[testing]] - Jest, Vitest testing

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

code-quality

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

game-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

devops-cicd

No summary provided by upstream source.

Repository SourceNeeds Review