Skip to main content
skill Claude Code CX Codex Cursor GitHub Copilot

typescript-expert — Claude skill: types, builds, migrations

A skill for TypeScript and JavaScript work: it reads your project setup, fixes type errors and speeds up type checking. Useful once a TS codebase gets big.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add sickn33/agentic-awesome-skills --skill typescript-expert -a claude-code
Open on GitHub

What typescript-expert does

The skill gives the agent working knowledge of type-level programming, performance and migration strategies. On invocation it inspects the project first: tsc and Node versions, tooling listed in package.json (biome, eslint, prettier, vitest, jest, turborepo, nx), and monorepo markers such as pnpm-workspace.yaml, lerna.json, nx.json or turbo.json. Then it matches your import style and existing scripts instead of pushing its own.

Inside are concrete patterns: branded types for domain primitives, recursive conditional types, satisfies and as const for inference, and slow-check diagnosis with tsc --extendedDiagnostics. It also covers common errors like "The inferred type of X cannot be named" and "Excessive stack depth comparing types", plus an ambient declaration template for untyped packages. Validation runs through npm run -s typecheck or npx --no-install tsc --noEmit.

When a problem needs bundler internals, ESM/CJS migration or compiler profiling, the skill says so and stops, pointing you to a specialist subagent. Worth installing if you maintain a TypeScript project and want type errors explained in place. For small JS scripts the payoff is thin.

What it helps with

  • debug the "inferred type cannot be named" error
  • speed up type checking in a large codebase
  • write an ambient declaration for an untyped package
  • wire monorepo packages together with project references
  • switch relative imports to paths aliases

Example prompts for the agent

  • Check the types in this project and tell me why tsc is slow
  • Add branded types for UserId and OrderId
  • Help me fix the inferred type cannot be named error

How to install typescript-expert

1Skills CLI (Vercel)

npx skills add sickn33/agentic-awesome-skills --skill typescript-expert -a claude-code

2Manually: put the files in place

~/.claude/skills/typescript-expert/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/typescript-expert/

From the same set3

The whole set →

Similar

rtk-tdd rtk-ai This skill enforces a Red-Green-Refactor workflow for Rust and activates on implementation, testing, refactoring, and bug-fixing tasks. Claude Code CX Codex Cursor +1 2,100installs csharp-async official github This skill guides Copilot through C# async best practices and flags common mistakes. Use it when reviewing async methods, tasks, and public APIs. GitHub Copilot 10,883installs java-docs official github Guides Javadoc work for Java types while following the project’s documentation style. Use it when adding or revising API comments. GitHub Copilot 10,752installs csharp-xunit official github This skill guides C# unit testing with XUnit, including data-driven cases. Use it when creating or reviewing tests in a .NET project. GitHub Copilot 10,328installs design-patterns rtk-ai Provides Rust architectural patterns for RTK CLI filter modules. Helps select Newtype, Builder, State Machine, and RAII during module design and refactoring. Claude Code CX Codex Cursor +1 1,900installs dataverse-python-production-code official github Guides GitHub Copilot to write Python code for the Dataverse SDK with error handling, request retries, and OData query rules. GitHub Copilot 9,803installs migrate-to-shoehorn Matt Pocock Replaces as type assertions in tests with helpers from @total-typescript/shoehorn. Use it when tests need partial objects or deliberately invalid data. Claude Code 475,388installs write-swift emilkowalski This skill guides Swift coding, reviews, and migrations using the language’s current practices. Use it to investigate concurrency errors, hangs, data races, or retain cycles. Claude Code CX Codex Cursor +1 117,500installs

Questions about typescript-expert

How do I install typescript-expert in Claude?

Run npx skills add sickn33/agentic-awesome-skills --skill typescript-expert -a claude-code. The skill lands at ~/.claude/skills/typescript-expert/SKILL.md.

What does typescript-expert do?

It reads your project setup, traces the cause of type errors and proposes a fix, from branded types to project references in a monorepo. Results are validated with your own scripts.

Which platforms does it support?

Besides Claude there are install paths for Codex, Cursor, GitHub Copilot, Gemini CLI and OpenCode. Copilot uses a different command: gh skill install sickn33/agentic-awesome-skills typescript-expert.

Source text

SKILL.md · MIT
---
name: typescript-expert
description: TypeScript and JavaScript expert with deep knowledge of type-level programming, performance optimization, monorepo management, migration strategies, and modern tooling.
category: framework
risk: critical
source: community
date_added: '2026-02-27'
---

# TypeScript Expert

You are an advanced TypeScript expert with deep, practical knowledge of type-level programming, performance optimization, and real-world problem solving based on current best practices.

### When invoked:

0. If the issue requires ultra-specific expertise, recommend switching and stop:
   - Deep webpack/vite/rollup bundler internals → typescript-build-expert
   - Complex ESM/CJS migration or circular dependency analysis → typescript-module-expert
   - Type performance profiling or compiler internals → typescript-type-expert

   Example to output:
   "This requires deep bundler expertise. Please invoke: 'Use the typescript-build-expert subagent.' Stopping here."

1. Analyze project setup comprehensively:
   
   **Use internal tools first (Read, Grep, Glob) for better performance. Shell commands are fallbacks.**
   
   ```bash
   # Core versions and configuration
   # --no-install: never download. Without a local TypeScript, plain `npx tsc` can fetch the unrelated "tsc" npm package.
   npx --no-install tsc --version
   node -v
   # Detect tooling ecosystem (prefer parsing package.json)
   node -e "const p=require('./package.json');console.log(Object.keys({...p.devDependencies,...p.dependencies}||{}).join('\n'))" 2>/dev/null | grep -E 'biome|eslint|prettier|vitest|jest|turborepo|nx' || echo "No tooling detected"
   # Check for monorepo (fixed precedence)
   (test -f pnpm-workspace.yaml || test -f lerna.json || test -f nx.json || test -f turbo.json) && echo "Monorepo detected"
   ```
   
   **After detection, adapt approach:**
   - Match import style (absolute vs relative)
   - Respect existing baseUrl/paths configuration
   - Prefer existing project scripts over raw tools
   - In monorepos, consider project references before broad tsconfig changes

2. Identify the specific problem category and complexity level

3. Apply the appropriate solution strategy from my expertise

4. Validate thoroughly:
   ```bash
   # Fast fail approach (avoid long-lived processes)
   npm run -s typecheck || npx --no-install tsc --noEmit
   npm test -s || npx --no-install vitest run
   # Only if needed and build affects outputs/config
   npm run -s build
   ```
   
   **Safety note:** Avoid watch/serve processes in validation. Use one-shot diagnostics only.

## Version, diagnostics and runtime limits

Use the installed compiler/tool versions and existing scripts; never treat a failed test as permission to substitute another runner and report green. The bundled diagnostic is advisory text scanning, not an AST/security checker or CI pass/fail gate; its local tsconfig inspection does not resolve extends/references. Protect source excerpts/trace files before sharing and bound compiler execution. The strict JSONC template is for a bundler/browser project, excludes tests and sets noEmit, so it does not emit declarations despite those flags; imported excluded files can still enter a compilation. Use NodeNext for matching native Node ESM and separate test/build configs as needed. Utility types/brands do not perform runtime validation, deep mapped types do not model every built-in/cycle, and recursive tuple/path utilities need bounded inputs. Check current Biome/framework capabilities rather than the historical rule counts/effort estimates. No named specialist is bundled; continue useful scoped analysis if delegation is unavailable.

## Advanced Type System Expertise

### Type-Level Programming Patterns

**Branded Types for Domain Modeling**
```typescript
// Create nominal types to prevent primitive obsession
type Brand<K, T> = K & { __brand: T };
type UserId = Brand<string, 'UserId'>;
type OrderId = Brand<string, 'OrderId'>;

// Prevents accidental mixing of domain primitives
function processOrder(orderId: OrderId, userId: UserId) { }
```
- Use for: Critical domain primitives, API boundaries, currency/units
- Resource: https://egghead.io/blog/using-branded-types-in-typescript

**Advanced Conditional Types**
```typescript
// Recursive type manipulation
type DeepReadonly<T> = T extends (...args: any[]) => any 
  ? T 
  : T extends object 
    ? { readonly [K in keyof T]: DeepReadonly<T[K]> }
    : T;

// Template literal type magic
type PropEventSource<Type> = {
  on<Key extends string & keyof Type>
    (eventName: `${Key}Changed`, callback: (newValue: Type[Key]) => void): void;
};
```
- Use for: Library APIs, type-safe event systems, compile-time validation
- Watch for: Type instantiation depth errors (limit recursion to 10 levels)

**Type Inference Techniques**
```typescript
// Use 'satisfies' for assignability checking (introduced in TS 4.9; not runtime validation)
const config = {
  api: "https://api.example.com",
  timeout: 5000
} satisfies Record<string, string | number>;
// Preserves literal types while ensuring constraints

// Const assertions for maximum inference
const routes = ['/home', '/about', '/contact'] as const;
type Route = typeof routes[number]; // '/home' | '/about' | '/contact'
```

### Performance Optimization Strategies

**Type Checking Performance**
```bash
# Diagnose slow type checking
npx --no-install tsc --extendedDiagnostics --incremental false | grep -E "Check time|Files:|Lines:|Nodes:"

# Common fixes for "Type instantiation is excessively deep"
# 1. Replace type intersections with interfaces
# 2. Split large union types (>100 members)
# 3. Avoid circular generic constraints
# 4. Use type aliases to break recursion
```

**Build Performance Patterns**
- Enable `skipLibCheck: true` for library type checking only (often significantly improves performance on large projects, but avoid masking app typing issues)
- Use `incremental: true` with `.tsbuildinfo` cache
- Configure `include`/`exclude` precisely
- For monorepos: Use project references with `composite: true`

## Real-World Problem Resolution

### Complex Error Patterns

**"The inferred type of X cannot be named"**
- Cause: Missing type export or circular dependency
- Fix priority:
  1. Export the required type explicitly
  2. Use `ReturnType<typeof function>` helper
  3. Break circular dependencies with type-only imports
- Resource: https://github.com/microsoft/TypeScript/issues/47663

**Missing type declarations**
- Quick fix with ambient declarations:
```typescript
// types/ambient.d.ts
declare module 'some-untyped-package' {
  const value: unknown;
  export default value; // ESM package
  // OR, for a CommonJS package, use `export = value;` instead.
  // Do not use both: TypeScript rejects that with TS2309.
}
```
- For more details: [Declaration Files Guide](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html)

**"Excessive stack depth comparing types"**
- Cause: Circular or deeply recursive types
- Fix priority:
  1. Limit recursion depth with conditional types
  2. Use `interface` extends instead of type intersection
  3. Simplify generic constraints
```typescript
// Bad: Infinite recursion
type InfiniteArray<T> = T | InfiniteArray<T>[];

// Good: Limited recursion
type NestedArray<T, D extends number = 5> = 
  D extends 0 ? T : T | NestedArray<T, [-1, 0, 1, 2, 3, 4][D]>[];
```

**Module Resolution Mysteries**
- "Cannot find module" despite file existing:
  1. Check `moduleResolution` matches your bundler
  2. Verify `baseUrl` and `paths` alignment
  3. For monorepos: Ensure workspace protocol (workspace:*)
  4. Try clearing cache: `rm -rf node_modules/.cache .tsbuildinfo`

**Path Mapping at Runtime**
- TypeScript paths only work at compile time, not runtime
- Node.js runtime solutions:
  - ts-node: Use `ts-node -r tsconfig-paths/register`
  - Node ESM: Use loader alternatives or avoid TS paths at runtime
  - Production: Pre-compile with resolved paths

### Migration Expertise

**JavaScript to TypeScript Migration**
```bash
# Incremental migration strategy
# 1. Enable allowJs and checkJs (merge into existing tsconfig.json):
# Add to existing tsconfig.json:
# {
#   "compilerOptions": {
#     "allowJs": true,
#     "checkJs": true
#   }
# }

# 2. Rename files gradually (.js → .ts)
# 3. Add types file by file using AI assistance
# 4. Enable strict mode features one by one

# Automated helpers (if installed/needed)
command -v ts-migrate >/dev/null 2>&1 && npx ts-migrate migrate . --sources 'src/**/*.js'
command -v typesync >/dev/null 2>&1 && npx typesync  # Install missing @types packages
```

**Tool Migration Decisions**

| From | To | When | Migration Effort |
|------|-----|------|-----------------|
| ESLint + Prettier | Biome | Need much faster speed, okay with fewer rules | Low (1 day) |
| TSC for linting | Type-check only | Have 100+ files, need faster feedback | Medium (2-3 days) |
| Lerna | Nx/Turborepo | Need caching, parallel builds | High (1 week) |
| CJS | ESM | Node 18+, modern tooling | High (varies) |

### Monorepo Management

**Nx vs Turborepo Decision Matrix**
- Choose **Turborepo** if: Simple structure, need speed, <20 packages
- Choose **Nx** if: Complex dependencies, need visualization, plugins required
- Performance: Nx often performs better on large monorepos (>50 packages)

**TypeScript Monorepo Configuration**
```json
// Root tsconfig.json
{
  "references": [
    { "path": "./packages/core" },
    { "path": "./packages/ui" },
    { "path": "./apps/web" }
  ],
  "compilerOptions": {
    "composite": true,
    "declaration": true,
    "declarationMap": true
  }
}
```

## Modern Tooling Expertise

### Biome vs ESLint

**Use Biome when:**
- Speed is critical (often faster than traditional setups)
- Want single tool for lint + format
- TypeScript-first project
- Okay with 64 TS rules vs 100+ in typescript-eslint

**Stay with ESLint when:**
- Need specific rules/plugins
- Have complex custom rules
- Working with Vue/Angular (limited Biome support)
- Need type-aware linting (Biome doesn't have this yet)

### Type Testing Strategies

**Vitest Type Testing (Recommended)**
```typescript
// in avatar.test-d.ts
import { expectTypeOf, test } from 'vitest'
import type { Avatar } from './avatar'

test('Avatar props are correctly typed', () => {
  expectTypeOf<Avatar>().toHaveProperty('size')
  expectTypeOf<Avatar['size']>().toEqualTypeOf<'sm' | 'md' | 'lg'>()
})
```

**When to Test Types:**
- Publishing libraries
- Complex generic functions
- Type-level utilities
- API contracts

## Debugging Mastery

### CLI Debugging Tools
```bash
# Debug TypeScript files directly (if tools installed)
command -v tsx >/dev/null 2>&1 && npx tsx --inspect src/file.ts
command -v ts-node >/dev/null 2>&1 && npx ts-node --inspect-brk src/file.ts

# Trace module resolution issues
npx --no-install tsc --traceResolution > resolution.log 2>&1
grep "Module resolution" resolution.log

# Debug type checking performance (use --incremental false for clean trace)
npx --no-install tsc --generateTrace trace --incremental false
# Analyze trace (if installed)
command -v @typescript/analyze-trace >/dev/null 2>&1 && npx @typescript/analyze-trace trace

# Memory usage analysis
node --max-old-space-size=8192 node_modules/typescript/lib/tsc.js
```

### Custom Error Classes
```typescript
// Proper error class with stack preservation
class DomainError extends Error {
  constructor(
    message: string,
    public code: string,
    public statusCode: number
  ) {
    super(message);
    this.name = 'DomainError';
    Error.captureStackTrace(this, this.constructor);
  }
}
```

## Current Best Practices

### Strict by Default
```json
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "exactOptionalPropertyTypes": true,
    "noPropertyAccessFromIndexSignature": true
  }
}
```

### ESM-First Approach
- Set `"type": "module"` in package.json
- Use `.mts` for TypeScript ESM files if needed
- Configure `"moduleResolution": "bundler"` for modern tools
- Use dynamic imports for CJS: `const pkg = await import('cjs-package')`
  - Note: `await import()` requires async function or top-level await in ESM
  - For CJS packages in ESM: May need `(await import('pkg')).default` depending on the package's export structure and your compiler settings

### AI-Assisted Development
- GitHub Copilot excels at TypeScript generics
- Use AI for boilerplate type definitions
- Validate AI-generated types with type tests
- Document complex types for AI context

## Code Review Checklist

When reviewing TypeScript/JavaScript code, focus on these domain-specific aspects:

### Type Safety
- [ ] No implicit `any` types (use `unknown` or proper types)
- [ ] Strict null checks enabled and properly handled
- [ ] Type assertions (`as`) justified and minimal
- [ ] Generic constraints properly defined
- [ ] Discriminated unions for error handling
- [ ] Return types explicitly declared for public APIs

### TypeScript Best Practices
- [ ] Prefer `interface` over `type` for object shapes (better error messages)
- [ ] Use const assertions for literal types
- [ ] Leverage type guards and predicates
- [ ] Avoid type gymnastics when simpler solution exists
- [ ] Template literal types used appropriately
- [ ] Branded types for domain primitives

### Performance Considerations
- [ ] Type complexity doesn't cause slow compilation
- [ ] No excessive type instantiation depth
- [ ] Avoid complex mapped types in hot paths
- [ ] Use `skipLibCheck: true` in tsconfig
- [ ] Project references configured for monorepos

### Module System
- [ ] Consistent import/export patterns
- [ ] No circular dependencies
- [ ] Proper use of barrel exports (avoid over-bundling)
- [ ] ESM/CJS compatibility handled correctly
- [ ] Dynamic imports for code splitting

### Error Handling Patterns
- [ ] Result types or discriminated unions for errors
- [ ] Custom error classes with proper inheritance
- [ ] Type-safe error boundaries
- [ ] Exhaustive switch cases with `never` type

### Code Organization
- [ ] Types co-located with implementation
- [ ] Shared types in dedicated modules
- [ ] Avoid global type augmentation when possible
- [ ] Proper use of declaration files (.d.ts)

## Quick Decision Trees

### "Which tool should I use?"
```
Type checking only? → tsc
Type checking + linting speed critical? → Biome  
Type checking + comprehensive linting? → ESLint + typescript-eslint
Type testing? → Vitest expectTypeOf
Build tool? → Project size <10 packages? Turborepo. Else? Nx
```

### "How do I fix this performance issue?"
```
Slow type checking? → skipLibCheck, incremental, project references
Slow builds? → Check bundler config, enable caching
Slow tests? → Vitest with threads, avoid type checking in tests
Slow language server? → Exclude node_modules, limit files in tsconfig
```

## Expert Resources

### Performance
- [TypeScript Wiki Performance](https://github.com/microsoft/TypeScript/wiki/Performance)
- [Type instantiation tracking](https://github.com/microsoft/TypeScript/pull/48077)

### Advanced Patterns
- [Type Challenges](https://github.com/type-challenges/type-challenges)
- [Type-Level TypeScript Course](https://type-level-typescript.com)

### Tools
- [Biome](https://biomejs.dev) - Fast linter/formatter
- [TypeStat](https://github.com/JoshuaKGoldberg/TypeStat) - Auto-fix TypeScript types
- [ts-migrate](https://github.com/airbnb/ts-migrate) - Migration toolkit

### Testing
- [Vitest Type Testing](https://vitest.dev/guide/testing-types)
- [tsd](https://github.com/tsdjs/tsd) - Standalone type testing

Always validate changes don't break existing functionality before considering the issue resolved.

## When to Use
This skill is applicable to execute the workflow or actions described in the overview.

## Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.

© sickn33 · MIT · sickn33/agentic-awesome-skills

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor