---
name: better-typescript
description: >
  Apply this skill for any task involving TypeScript: writing new code,
  refactoring, reviewing, debugging, designing types, structuring modules, or answering questions
  about TS patterns. Use it whenever the user mentions TypeScript, .ts/.tsx files,
  types, interfaces, generics, or any TS ecosystem (Node, Deno, Bun, React, Next.js,
  tRPC, Zod, etc.) — even if the question seems simple.
license: MIT
---

# TypeScript Skill

This skill extends the main foundations of how Claude Code approaches TypeScript,
providing a more detailed and specific approach for writing high-quality TS code.

## General Philosophy

- **Correctness first**: code must be correct before being elegant.
- **Types as documentation**: types are explicit contracts, not a formality. If a type
  says `string`, it must always be `string` — not accidentally `string | undefined`.
- **Explicit over implicit**: prefer clarity over brevity when there is ambiguity.
- **No `any` without justification**: `any` is technical debt. If used, the reason must be commented.

---

## Default Assumed Configuration

Unless the user indicates otherwise, assume:

```json
// tsconfig.json (strict mode)
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "bundler",
    "target": "ES2024",
    "module": "ESNext"
  }
}
```

```json
// .prettierrc (for consistent formatting)
{
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 100
}
```

If the project has a `tsconfig.json` and/or `.prettierrc` visible in context, read it **first**
and adjust all suggestions to that real configuration.

---

## Types and Structures

See [Type Preferences](./references/types.md) for details.

---

## Code Patterns

See [Code Patterns](./references/code-patterns.md) for details.

---

## Runtime Validation

See [Runtime Validation](./references/runtime-validation.md) for details.

---

## Module Organization

See [Module Organization](./references/module-organization.md) for details.

Always:

- One file = one clear responsibility.
- Re-export from `index.ts` only what is public API of the module.
- Avoid circular imports — if they appear, it's a sign of a missing module.

---

## Programming Paradigms

See [Programming Paradigms](./references/paradigms.md) for details.

---

## Metaprogramming

See [Metaprogramming](./references/metaprogramming.md) for details.

---

## Comments

See [Comments](./references/comments.md) for details.

## Naming Conventions

| Element                | Convention           | Example                     |
|------------------------|----------------------|-----------------------------|
| Variables / functions  | camelCase            | `getUserById`               |
| Types / Interfaces     | PascalCase           | `UserRepository`            |
| Global constants       | SCREAMING_SNAKE_CASE | `MAX_RETRIES`               |
| Files                  | kebab-case           | `user-repository.ts`        |
| Booleans               | prefix `is/has/can`  | `isActive`, `hasPermission` |
| Simple generics        | T, U, K, V           | `Array<T>`                  |
| Descriptive generics   | PascalCase           | `Result<TValue, TError>`    |

Files can be named with an optional suffix indicating their purpose, like `.service.ts`, `.controller.ts`, `.types.ts`, etc.,
for example `user-identity.service.ts` for a service related to user identity.

---

## Generics

```typescript
// ✅ Constrain when the generic has real requirements
function getProperty<TTarget, TKey extends keyof TTarget>(obj: TTarget, key: TKey): TTarget[TKey] {
  return obj[key];
}

// ✅ Default types for APIs with good DX
type Paginated<T = unknown> = { items: T[]; total: number; page: number };

// ❌ Do not use generics just to look flexible — if it is always string, it is string
function logMessage<T>(message: T): void {
  console.log(message);
}
```

---

## Checklist before delivering code

- [ ] Does it compile with `strict: true`?
- [ ] Is there any unjustified `any`?
- [ ] Are expected errors handled (not just network/runtime)?
- [ ] Do exported functions have explicit returns?
- [ ] Does external data pass through a validation schema?
- [ ] Do tests cover narrowing edge cases?

---

## Ecosystem Context

Read the relevant section based on the detected stack in the project:

- **Node.js / APIs**: prefer native `fetch` (Node 18+), `AsyncLocalStorage` for context,
  consider tRPC or Hono for end-to-end type-safety.
- **React / Next.js**: typed components with `FC` only if explicit `children` is needed,
  prefer `JSX.Element` or `ReactNode` returns depending on the case.
- **Deno / Bun**: leverage global types of the runtime — do not install `@types/node`
  unnecessarily.
- **Testing**: Vitest > Jest for new projects (better type inference in mocks).

---

## Notes:

- Before writing code, read the project's `tsconfig.json` and `package.json` files
  to understand the target, runtime, and available dependencies.
- If a linter is detected (`.eslintrc`, `biome.json`, etc.), respect its rules.
- Prefer editing the existing file over creating a new one unless it is clearly
  a new addition to the project.
- When refactoring: make the minimal change that improves the situation, do not rewrite everything.
