typescript-core — Claude Code skill: TypeScript patterns
A skill with modern TypeScript patterns: a strict tsconfig, runtime validation, advanced types. Useful once a TS codebase outgrows its type setup.
npx skills add bobmatnyc/claude-mpm-skills --skill typescript-core -a claude-codeWhat typescript-core does
The skill walks through TypeScript project setup: a baseline tsconfig.json with strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes and verbatimModuleSyntax, plus a table of key compiler options and when to turn each on. Then come type patterns — const type parameters, the satisfies operator, template literal types, discriminated unions with exhaustiveness checks.
A separate section covers runtime validation. TypeScript types vanish at runtime, so for API responses, forms and config files it points to Zod, TypeBox or Valibot, with a comparison of bundle size and speed. There are decision trees for type versus interface and generics versus unions, plus a troubleshooting list for common compiler errors.
Inside you get an entry point with a summary and a set of reference files: advanced-types.md, configuration.md, runtime-validation.md, advanced-patterns-2025.md, decision-trees.md, troubleshooting.md, js-quality-antipatterns.md. The skill is not user-invocable and disables model invocation, so it loads as a reference rather than a command. It targets TS 5.2 and later — on older versions the using and decorator examples will not compile.
What it helps with
- turn on strict mode in an existing project without a flood of errors
- swap
anyforunknownwhere external data gets parsed - pick a validation library that fits the bundle budget
- keep literal types in a config object with
satisfies - figure out why compilation got slow
Example prompts for the agent
- Set up tsconfig for a new TypeScript project using the typescript-core patterns
- Check this file against the typescript-core antipatterns
- Help me choose between Zod and TypeBox for validating API responses
How to install typescript-core
1Skills CLI (Vercel)
npx skills add bobmatnyc/claude-mpm-skills --skill typescript-core -a claude-code2Manually: put the files in place
~/.claude/skills/typescript-core/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/typescript-core/
1Skills CLI (Vercel)
npx skills add bobmatnyc/claude-mpm-skills --skill typescript-core -a codex2Manually: put the files in place
.agents/skills/typescript-core/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add bobmatnyc/claude-mpm-skills --skill typescript-core -a cursor2Manually: put the files in place
.cursor/skills/typescript-core/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install bobmatnyc/claude-mpm-skills typescript-core2Manually: put the files in place
.github/skills/typescript-core/SKILL.md1Skills CLI (Vercel)
npx skills add bobmatnyc/claude-mpm-skills --skill typescript-core -a gemini-cli2Platform CLI
gemini skills install https://github.com/bobmatnyc/claude-mpm-skills --path toolchains/typescript/typescript-coreManually: put the files in place
.devin/skills/typescript-core/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add bobmatnyc/claude-mpm-skills --skill typescript-core -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about typescript-core
How do I install typescript-core in Claude?
Run npx skills add bobmatnyc/claude-mpm-skills --skill typescript-core -a claude-code. The skill file lands at ~/.claude/skills/typescript-core/SKILL.md.
What does typescript-core do?
It collects TypeScript patterns: a baseline tsconfig, advanced types, runtime validation and decision trees. It acts as a reference the agent pulls in when needed.
Which TypeScript versions does the skill cover?
The material targets TS 5.2 and later. The using and decorator examples will not compile on older versions.
Source text
SKILL.md · MIT
---
name: typescript-core
description: "Advanced TypeScript patterns and best practices for 2025"
user-invocable: false
disable-model-invocation: true
version: 1.2.0
updated: "2026-06-15"
progressive_disclosure:
entry_point:
summary: "Type-safe TypeScript patterns with optimal tsconfig, runtime validation, and modern TS 5.2+ features"
when_to_use: "When working with TypeScript requiring advanced types, strict configuration, runtime validation, or modern language features (using, decorators)"
quick_start: "1. Start with tsconfig baseline 2. Apply core type patterns (const, satisfies) 3. Integrate runtime validation (Zod/TypeBox) 4. Use modern features (using, decorators) as needed"
references:
- advanced-types.md
- configuration.md
- runtime-validation.md
- advanced-patterns-2025.md
- decision-trees.md
- troubleshooting.md
- js-quality-antipatterns.md
---
# TypeScript Core Patterns
Modern TypeScript development patterns for type safety, runtime validation, and optimal configuration.
## Quick Start
**New Project:** Use 2025 tsconfig → Enable `strict` + `noUncheckedIndexedAccess` → Choose Zod for validation
**Existing Project:** Enable `strict: false` initially → Fix `any` with `unknown` → Add `noUncheckedIndexedAccess`
**API Development:** Zod schemas at boundaries → `z.infer<typeof Schema>` for types → `satisfies` for routes
**Library Development:** Enable `declaration: true` → Use `const` type parameters → See [advanced-patterns-2025.md](./references/advanced-patterns-2025.md)
## Quick Reference
### tsconfig.json 2025 Baseline
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"verbatimModuleSyntax": true,
"isolatedModules": true,
"skipLibCheck": true,
"declaration": true,
"declarationMap": true
}
}
```
### Key Compiler Options
| Option | Purpose | When to Enable |
|--------|---------|----------------|
| `noUncheckedIndexedAccess` | Forces null checks on array/object access | Always for safety |
| `exactOptionalPropertyTypes` | Distinguishes `undefined` from missing | APIs with optional fields |
| `verbatimModuleSyntax` | Enforces explicit type-only imports | ESM projects |
| `erasableSyntaxOnly` | Node.js 22+ native TS support | Type stripping environments |
## Local Baselines
See `references/configuration.md` for repo-specific tsconfig patterns (CommonJS CLI, NodeNext strict, Next.js bundler).
## Core Type Patterns
### Const Type Parameters
Preserve literal types through generic functions:
```typescript
function createConfig<const T extends Record<string, unknown>>(config: T): T {
return config;
}
const config = createConfig({
apiUrl: "https://api.example.com",
timeout: 5000
});
// Type: { readonly apiUrl: "https://api.example.com"; readonly timeout: 5000 }
```
### Satisfies Operator
Validate against a type while preserving literal inference:
```typescript
type Route = { path: string; children?: Routes };
type Routes = Record<string, Route>;
const routes = {
AUTH: { path: "/auth" },
HOME: { path: "/" }
} satisfies Routes;
routes.AUTH.path; // Type: "/auth" (literal preserved)
routes.NONEXISTENT; // ❌ Type error
```
### Template Literal Types
Type-safe string manipulation and route extraction:
```typescript
type ExtractParams<T extends string> =
T extends `${string}:${infer Param}/${infer Rest}`
? Param | ExtractParams<Rest>
: T extends `${string}:${infer Param}`
? Param
: never;
type Params = ExtractParams<"/users/:id/posts/:postId">; // "id" | "postId"
```
### Discriminated Unions with Exhaustiveness
```typescript
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
function handleResult<T>(result: Result<T>): T {
if (result.success) return result.data;
throw result.error;
}
// Exhaustiveness checking
type Action =
| { type: 'create'; payload: string }
| { type: 'delete'; id: number };
function handle(action: Action) {
switch (action.type) {
case 'create': return action.payload;
case 'delete': return action.id;
default: {
const _exhaustive: never = action;
throw new Error(`Unhandled: ${_exhaustive}`);
}
}
}
```
## Runtime Validation
TypeScript types disappear at runtime. Use validation libraries for external data (APIs, forms, config files).
### Quick Comparison
| Library | Bundle Size | Speed | Best For |
|---------|-------------|-------|----------|
| **Zod** | ~13.5kB | Baseline | Full-stack apps, tRPC integration |
| **TypeBox** | ~8kB | ~10x faster | OpenAPI, performance-critical |
| **Valibot** | ~1.4kB | ~2x faster | Edge functions, minimal bundles |
### Basic Pattern (Zod)
```typescript
import { z } from "zod";
const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
role: z.enum(["admin", "user", "guest"]),
});
type User = z.infer<typeof UserSchema>;
// Validate external data
function parseUser(input: unknown): User {
return UserSchema.parse(input);
}
```
**→ See [runtime-validation.md](./references/runtime-validation.md) for complete Zod, TypeBox, and Valibot patterns**
## Decision Support
### Quick Decision Guide
**Need to choose between `type` vs `interface`?**
- Public API / library types → `interface`
- Union types / mapped types → `type`
- Simple object shapes → `interface` (default)
**Need generics or union types?**
- Output type depends on input type → Generics
- Fixed set of known types → Union types
- Building reusable data structures → Generics
**Dealing with unknown data?**
- External data (API, user input) → `unknown` (type-safe)
- Rapid prototyping / migration → `any` (temporarily)
**Need runtime validation?**
- Full-stack TypeScript with tRPC → Zod
- OpenAPI / high performance → TypeBox
- Edge functions / minimal bundle → Valibot
**→ See [decision-trees.md](./references/decision-trees.md) for comprehensive decision frameworks**
## Troubleshooting
### Common Issues Quick Reference
**Property does not exist on type** → Define proper interface or use optional properties
**Type is not assignable** → Fix property types or use runtime validation (Zod)
**Object is possibly 'undefined'** → Use optional chaining (`?.`) or type guards
**Cannot find module** → Check file extensions (.js for ESM) and module resolution
**Slow compilation** → Enable `incremental`, use `skipLibCheck`, consider esbuild/swc
**→ See [troubleshooting.md](./references/troubleshooting.md) for detailed solutions with examples**
## Navigation
### Detailed References
- **[📐 Advanced Types](./references/advanced-types.md)** - Conditional types, mapped types, infer keyword, recursive types. Load when building complex type utilities or generic libraries.
- **[⚙️ Configuration](./references/configuration.md)** - Complete tsconfig.json guide, project references, monorepo patterns. Load when setting up new projects or optimizing builds.
- **[🔒 Runtime Validation](./references/runtime-validation.md)** - Zod, TypeBox, Valibot deep patterns, error handling, integration strategies. Load when implementing API validation or form handling.
- **[✨ Advanced Patterns 2025](./references/advanced-patterns-2025.md)** - TypeScript 5.2+ features: `using` keyword, stable decorators, import type behavior, satisfies with generics. Load when using modern language features.
- **[🌳 Decision Trees](./references/decision-trees.md)** - Clear decision frameworks for `type` vs `interface`, generics vs unions, `unknown` vs `any`, validation library selection, type narrowing strategies, and module resolution. Load when making TypeScript design decisions.
- **[🔧 Troubleshooting](./references/troubleshooting.md)** - Common TypeScript errors and fixes, type inference issues, module resolution problems, tsconfig misconfigurations, build performance optimization, and type compatibility errors. Load when debugging TypeScript issues.
## JavaScript / Runtime Quality Anti-Patterns
The type system catches type errors, but a class of JavaScript defects is **runtime/AST-
level** and survives into emitted JS and plain-JS files. Watch for:
- **Loose equality** (`==`/`!=`) — coercion bugs and auth flaws; use `===`/`!==` (accept
`== null` only when commented as "null or undefined").
- **Dynamic code execution** (`eval`, `new Function(str)`, string `setTimeout`) — injection
risk and unnecessary; use direct syntax.
- **Mutating builtins** (`Object`/`Array`/`Function.prototype`) — pollutes `for…in`,
breaks the whole runtime; extend or use free functions instead.
- **Variable shadowing**, **`var` instead of `let`/`const`**, **using functions before
declaration** — readability and "wrong variable" bugs.
- **Logical OR in `switch` case labels** (`case 1 || 2:` only matches 1) — use stacked
case labels.
- **Repetitive deep-member access** — cache the resolved chain in a local (esp. DOM).
- **Non-wrapped IIFEs**, **backslash multiline strings**, **`new Array()`** — readability
and well-known traps; prefer wrapped IIFEs, template literals, and array literals.
See **[JS/TS Quality Anti-Patterns](./references/js-quality-antipatterns.md)** for each
defect with compliant/non-compliant examples, severities, false-positive filters, and the
equivalent ESLint/SonarSource rule. Derived from CAST Highlight JavaScript code quality
indicators (https://doc.casthighlight.com/), cross-referenced to ESLint core rules and
SonarSource RSPEC.
## Red Flags
**Stop and reconsider if:**
- Using `any` instead of `unknown` for external data
- Casting with `as` without runtime validation
- Disabling strict mode for convenience
- Using `@ts-ignore` without clear justification
- Index access without `noUncheckedIndexedAccess`
## Integration with Other Skills
- **nextjs-core**: Type-safe Server Actions and route handlers
- **nextjs-v16**: Async API patterns and Cache Components typing
- **mcp-builder**: Zod schemas for MCP tool inputs
## Related Skills
When using Core, these skills enhance your workflow:
- **react**: TypeScript with React: component typing, hooks, generics
- **nextjs**: TypeScript in Next.js: Server Components, Server Actions typing
- **drizzle**: Type-safe database queries with Drizzle ORM
- **prisma**: Prisma's generated TypeScript types for database schemas
[Full documentation available in these skills if deployed in your bundle]
© bobmatnyc · MIT · bobmatnyc/claude-mpm-skills