# typescript-best-practices

A skill that hands the agent a rulebook for .ts and .tsx files: discriminated unions, branded types, validation at the boundary.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 7900 installs · ★ 14099
- Author: cursor
- License: not stated · policy=link-only · description only; the file stays with the author
- Source: https://github.com/cursor/plugins/tree/HEAD/pstack/skills/typescript-best-practices/SKILL.md
- Updated: 2026-10-25
- HTML: https://affpapa.org/en/nevibecode/skills/typescript-best-practices

## What it does

The skill fires whenever the agent opens or edits a `.ts` or `.tsx` file. Its table of rules covers modeling variants with a literal `kind` discriminant, branding primitives via `& { readonly __brand: "X" }`, and keeping outside data in `unknown` rather than `any`.

A second group deals with narrowing. The order runs from a discriminant `switch` down to `as`, user-defined type guards have to actually verify what they claim, and default arms carry `const _exhaustive: never = x;` so a new variant breaks the build. Schemas come before hand-written guards, with the type inferred from the schema, `z.infer` being the example given. Every `as` is treated as a runtime crash waiting to happen — cast only after validation.

Two principle skills are named as prerequisites: **type-system-discipline** and **boundary-discipline**, applied first. Pattern examples live in `references/patterns.md`. Install runs through `npx skills add` with a per-platform flag; GitHub Copilot takes a different command, `gh skill install`.

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add cursor/plugins --skill typescript-best-practices -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/typescript-best-practices/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/typescript-best-practices/

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add cursor/plugins --skill typescript-best-practices -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/typescript-best-practices/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add cursor/plugins --skill typescript-best-practices -a cursor
```

2. **Manually: put the files in place**
- File: `.cursor/skills/typescript-best-practices/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install cursor/plugins typescript-best-practices
```

2. **Manually: put the files in place**
- File: `.github/skills/typescript-best-practices/SKILL.md`

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add cursor/plugins --skill typescript-best-practices -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/cursor/plugins --path pstack/skills/typescript-best-practices
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/typescript-best-practices/SKILL.md` — The legacy .windsurf/skills/ path still works

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add cursor/plugins --skill typescript-best-practices -a opencode
```

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/cursor/plugins/tree/HEAD/pstack/skills/typescript-best-practices/SKILL.md

## When to use it
- model state variants so impossible combinations fail to compile
- swap scattered `as` casts for boundary validation and named domain types
- infer a type from a runtime schema instead of hand-writing a property guard
- add an exhaustiveness check that catches a new variant at build time
- move shipped code off `console.log` onto a structured logger

## Example prompts
- Review this `.ts` file against the skill rules and drop every `as`
- Rewrite this optional-field bag as a discriminated union on `kind`
- Add an exhaustiveness check to the `switch` over API response variants

## Similar
- [migrate-to-shoehorn](https://affpapa.org/en/nevibecode/skills/migrate-to-shoehorn.md) — skill · 475388 installs
- [write-swift](https://affpapa.org/en/nevibecode/skills/write-swift.md) — skill · 119300 installs
- [megacave](https://affpapa.org/en/nevibecode/skills/megacave.md) — skill · 25400 installs
- [find-docs](https://affpapa.org/en/nevibecode/skills/find-docs.md) — skill · 9400 installs
- [typescript-advanced-types](https://affpapa.org/en/nevibecode/skills/typescript-advanced-types.md) — skill · 92169 installs
- [smart-explore](https://affpapa.org/en/nevibecode/skills/smart-explore.md) — skill · 7300 installs

From the same set: [cursor/plugins](https://affpapa.org/en/nevibecode/by/cursor/plugins.md) — 47 cards

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
