Skip to main content

typescript-dev

This skill should be used when writing TypeScript, eliminating any types, implementing Zod validation, or when strict type safety is needed. Covers modern TS 5.5+ features and runtime validation patterns.

Quellinformationen

Repository
outfitter-dev/agents
Letzte Quellaktivität
27. Januar 2026 um 15:45
Erkannte Sprache von SKILL.md
Englisch
Sterne
28
Forks
1

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
15 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
typescript-dev
description
This skill should be used when writing TypeScript, eliminating any types, implementing Zod validation, or when strict type safety is needed. Covers modern TS 5.5+ features and runtime validation patterns.
metadata
{"version":"1.0.0"}
# TypeScript Development Type-safe code = compile-time errors = runtime confidence. <when_to_use> - Writing new TypeScript code - Eliminating `any` types - Using modern TypeScript 5.5+ features - Validating API inputs/outputs with Zod - Implementing Result types and discriminated unions - Creating branded types for domain concepts NOT for: runtime-only logic unrelated to types, non-TypeScript projects </when_to_use> <config> **tsconfig.json** strict settings: ```json { "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noFallthroughCasesInSwitch": true, "noImplicitReturns": true, "forceConsistentCasingInFileNames": true, "verbatimModuleSyntax": true, "isolatedModules": true, "skipLibCheck": false } } ``` **Version requirements**: TS 5.2+ (`using`), TS 5.4+ (`NoInfer`), TS 5.5+ (inferred predicates) </config> ## Core Patterns <eliminating_any> `any` defeats the type system. Use `unknown` + guards. ```typescript // ❌ NEVER function process(data: any) { return data.value; } // ✅ ALWAYS function process(data: unknown): string { if (!hasValue(data)) throw new TypeError('Invalid'); return data.value.toString(); } function hasValue(v: unknown): v is { value: unknown } { return typeof v === 'object' && v !== null && 'value' in v; } ``` Validate at boundaries: ```typescript async function fetchUser(id: string): Promise<User> { const data: unknown = await fetch(`/api/users/${id}`).then(r => r.json()); return UserSchema.parse(data); } ``` </eliminating_any> <result_types> Exceptions hide errors from types. Result makes them explicit. ```typescript type Result<T, E = Error> = | { readonly ok: true; readonly value: T } | { readonly ok: false; readonly error: E }; type UserError = | { readonly type: 'not-found'; readonly id: string } | { readonly type: 'network'; readonly message: string }; async function getUser(id: string): Promise<Result<User, UserError>> { try { const response = await fetch(`/api/users/${id}`); if (response.status === 404) return { ok: false, error: { type: 'not-found', id } }; if (!response.ok) return { ok: false, error: { type: 'network', message: response.statusText } }; return { ok: true, value: await response.json() }; } catch (e) { return { ok: false, error: { type: 'network', message: String(e) } }; } } // Caller must handle const result = await getUser(id); if (!result.ok) { switch (result.error.type) { case 'not-found': return showNotFound(result.error.id); case 'network': return showError(result.error.message); } } return renderUser(result.value); ``` See [result-pattern.md](references/result-pattern.md) for utilities (`map`, `flatMap`, `combine`). </result_types> <discriminated_unions> Prevent illegal state combinations. ```typescript // ❌ Allows { status: 'loading', data: user, error: 'Failed' } type Request = { status: 'idle'|'loading'|'success'|'error'; data?: User; error?: string; }; // ✅ Only valid states type RequestState = | { readonly status: 'idle' } | { readonly status: 'loading' } | { readonly status: 'success'; readonly data: User } | { readonly status: 'error'; readonly error: string }; function render(state: RequestState): JSX.Element { switch (state.status) { case 'idle': return <div>Ready</div>; case 'loading': return <div>Loading...</div>; case 'success': return <div>{state.data.name}</div>; case 'error': return <div>Error: {state.error}</div>; default: return assertNever(state); } } function assertNever(value: never): never { throw new Error(`Unhandled: ${JSON.stringify(value)}`); } ``` </discriminated_unions> <branded_types> Prevent mixing incompatible primitives. ```typescript declare const __brand: unique symbol; type Brand<T, B extends string> = T & { readonly [__brand]: B }; type UserId = Brand<string, 'UserId'>; type ProductId = Brand<string, 'ProductId'>; function createUserId(value: string): UserId { if (!/^user-\d+$/.test(value)) throw new TypeError(`Invalid: ${value}`); return value as UserId; } const userId = createUserId('user-123'); // getUser(productId); // ❌ Type error getUser(userId); // ✅ Works ``` Security: ```typescript type SanitizedHtml = Brand<string, 'SanitizedHtml'>; function sanitize(raw: string): SanitizedHtml { return escapeHtml(raw) as SanitizedHtml; } function render(html: SanitizedHtml): void { element.innerHTML = html; // Type proves sanitization } ``` See [branded-types.md](references/branded-types.md) for advanced patterns. </branded_types> ## Modern TypeScript (5.2+) <resource_management> `using` for automatic cleanup (TS 5.2+): ```typescript class DatabaseConnection implements Disposable { [Symbol.dispose]() { this.close(); } } function query() { using conn = new DatabaseConnection(); return conn.query('SELECT * FROM users'); } // Automatically closed async function asyncWork() { await using resource = new AsyncResource(); } // Disposed with await ``` Use for: connections, file handles, locks, transactions. </resource_management> <satisfies_operator> Validate type without widening (TS 4.9+): ```typescript const config = { port: 3000, host: 'localhost' } satisfies Record<string, string | number>; config.port // number (not string | number) const routes = { home: '/', user: '/user/:id' } as const satisfies Record<string, string>; type HomeRoute = typeof routes.home; // '/' ``` </satisfies_operator> <const_type_parameters> Preserve literals through generics (TS 5.0+): ```typescript function makeTuple<const T extends readonly unknown[]>(...args: T): T { return args; } const result = makeTuple('a', 'b', 'c'); // ['a', 'b', 'c'] not string[] ``` </const_type_parameters> <inferred_predicates> TS 5.5+ auto-infers type predicates: ```typescript function isString(x: unknown) { return typeof x === 'string'; } // Inferred: (x: unknown) => x is string const strings = values.filter(isString); // string[] ``` </inferred_predicates> <template_literals> Pattern matching at type level: ```typescript type Route = `/${string}`; type ApiRoute = `/api/v${number}/${string}`; type ExtractParams<T extends string> = T extends `${string}:${infer P}/${infer R}` ? P | ExtractParams<`/${R}`> : T extends `${string}:${infer P}` ? P : never; type Params = ExtractParams<'/user/:id/post/:postId'>; // 'id' | 'postId' ``` See [modern-features.md](references/modern-features.md) for TS 5.5-5.8. </template_literals> ## Zod Validation Schema = runtime validation + TypeScript type. <zod_core> ```typescript import { z } from 'zod'; const UserSchema = z.object({ id: z.string().uuid(), email: z.string().email(), name: z.string().min(1).max(100) }); type User = z.infer<typeof UserSchema>; // safeParse preferred const result = UserSchema.safeParse(data); if (!result.success) { console.error(result.error.issues); return; } const user = result.data; ``` </zod_core> <zod_patterns> **Discriminated unions** (preferred over z.union): ```typescript const ApiResponse = z.discriminatedUnion("type", [ z.object({ type: z.literal("success"), data: z.unknown() }), z.object({ type: z.literal("error"), code: z.string(), message: z.string() }) ]); ``` **Environment variables**: ```typescript const EnvSchema = z.object({ NODE_ENV: z.enum(['development', 'production', 'test']).default('development'), DATABASE_URL: z.string().url(), PORT: z.coerce.number().int().positive().default(3000) }); const env = EnvSchema.parse(process.env); ``` **API validation (Hono)**: ```typescript import { zValidator } from '@hono/zod-validator'; app.post('/users', zValidator('json', UserSchema), (c) => { const user = c.req.valid('json'); return c.json(user); }); ``` See: - [zod-building-blocks.md](references/zod-building-blocks.md) - primitives, refinements, transforms - [zod-schemas.md](references/zod-schemas.md) - composition patterns - [zod-integration.md](references/zod-integration.md) - API/form/env integration </zod_patterns> ## Type Guards ```typescript // User-defined function isString(v: unknown): v is string { return typeof v === 'string'; } // Assertion function assertString(v: unknown): asserts v is string { if (typeof v !== 'string') throw new TypeError('Expected string'); } // With noUncheckedIndexedAccess const users: User[] = getUsers(); const first = users[0]; // User | undefined if (first !== undefined) processUser(first); ``` See [advanced-types.md](references/advanced-types.md) for utilities. ## TSDoc Types show structure. TSDoc shows intent. Critical for AI agents. ```typescript /** * Authenticates user and returns session token. * @param credentials - User login credentials * @returns Session token valid for 24 hours * @throws {AuthenticationError} Invalid credentials * @example * const token = await authenticate({ email, password }); */ export async function authenticate(credentials: Credentials): Promise<SessionToken>; ``` Document: all exports, parameters with constraints, thrown errors, non-obvious returns. See [tsdoc-patterns.md](references/tsdoc-patterns.md) for comprehensive guide. <rules> ALWAYS: - Strict TypeScript config enabled - Type-only imports: `import type { User } from './types'` - Const assertions for literal types - Exhaustive matching with `assertNever` - Runtime validation at boundaries (Zod) - Branded types for domain/sensitive data - Result types for error-prone operations - `satisfies` for literal inference - `using` for resources with cleanup - TSDoc on all exports NEVER: - `any` (use `unknown` + guards) - `@ts-ignore` (fix types or document) - TypeScript enums (use const assertions or z.enum)
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen