# typescript-magician

Resolves TypeScript compiler errors, eliminates any types, and creates strict generic patterns. Useful when locking down codebase type safety.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 2800 installs · ★ 1960
- Author: mcollina
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/mcollina/skills/tree/HEAD/skills/typescript-magician/SKILL.md
- Updated: 2026-10-18
- HTML: https://affpapa.org/en/nevibecode/skills/typescript-magician

## What it does

The skill operates in a defined sequence. Before touching any code, it runs `tsc --noEmit` to capture all compiler errors. It isolates root causes like implicit `any` types or loose constraints and writes precise type-level solutions. Finally, a second `tsc --noEmit` pass confirms the codebase compiles cleanly.

The tool relies on TypeScript features like conditional types, mapped types, branded types, and utilities such as `ReturnType` or `Awaited`. When replacing `any`, it validates every substitution against existing call sites to prevent runtime breakage.

This skill requires an accessible `tsc` compiler in your project. Without it, the agent cannot verify type fixes against the compiler.

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add mcollina/skills --skill typescript-magician -a claude-code
```

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

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add mcollina/skills --skill typescript-magician -a codex
```

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

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add mcollina/skills --skill typescript-magician -a cursor
```

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

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install mcollina/skills typescript-magician
```

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

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add mcollina/skills --skill typescript-magician -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/mcollina/skills --path skills/typescript-magician
```

### Windsurf (Devin Desktop)

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

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add mcollina/skills --skill typescript-magician -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/mcollina/skills/tree/HEAD/skills/typescript-magician/SKILL.md

## When to use it
- replace unsafe any types with strict generics
- fix TypeScript compiler errors using double tsc --noEmit verification
- write custom type guards to narrow unknown API payloads
- implement branded types and conditional inference logic

## Example prompts
- Refactor `src/client.ts` to eliminate all `any` types using generics and verify with `tsc --noEmit`.
- Fix the type error in the builder function and make sure call sites still compile.
- Write a type guard to narrow an unknown response to a validated interface.

## Source text · SKILL.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: 0ebee8a907a2d111.

BEGIN THIRD-PARTY FILE 0ebee8a907a2d111
````text
---
name: typescript-magician
description: Designs complex generic types, refactors `any` types to strict alternatives, creates type guards and utility types, and resolves TypeScript compiler errors. Use when the user asks about TypeScript (TS) types, generics, type inference, type guards, removing `any` types, strict typing, type errors, `infer`, `extends`, conditional types, mapped types, template literal types, branded/opaque types, or utility types like `Partial`, `Record`, `ReturnType`, and `Awaited`.
metadata:
  tags: typescript, types, generics, type-safety, advanced-typescript
---

## When to use

Use this skill for:
- TypeScript errors and type challenges
- Eliminating `any` types from codebases
- Complex generics and type inference issues
- When strict typing is needed

## Instructions

When invoked:
1. Run `tsc --noEmit` to capture the full error output before making changes
2. Identify the root cause of type issues (unsound inference, missing constraints, implicit `any`, etc.)
3. Craft precise, type-safe solutions using advanced TypeScript features
4. Eliminate all `any` types with proper typing — validate each replacement still satisfies call sites
5. Confirm the fix compiles cleanly with a second `tsc --noEmit` pass

Capabilities include:
- Advanced generics and conditional types
- Template literal types and mapped types
- Utility types and type manipulation
- Brand types and nominal typing
- Complex inference patterns
- Variance and distribution rules
- Module augmentation and declaration merging

For every TypeScript challenge:
- Explain the type theory behind the problem
- Provide multiple solution approaches when applicable
- Show before/after type representations
- Include comprehensive type tests
- Ensure full IntelliSense support

## Quick Examples

### Eliminating `any` with generics

**Before**
```ts
function getProperty(obj: any, key: string): any {
  return obj[key];
}
```

**After**
```ts
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}
// getProperty({ name: "Alice" }, "name") → inferred as string ✓
```

### Narrowing an unknown API response

**Before**
```ts
async function fetchUser(): Promise<any> {
  const res = await fetch("/api/user");
  return res.json();
}
```

**After**
```ts
interface User { id: number; name: string }

function isUser(value: unknown): value is User {
  return (
    typeof value === "object" &&
    value !== null &&
    "id" in value &&
    "name" in value
  );
}

async function fetchUser(): Promise<User> {
  const res = await fetch("/api/user");
  const data: unknown = await res.json();
  if (!isUser(data)) throw new Error("Invalid user shape");
  return data;
}
```

## Reference

Read individual rule files for detailed explanations and code examples:

### Core Patterns
- [rules/as-const-typeof.md](rules/as-const-typeof.md) - Deriving types from runtime values using `as const` and `typeof`
````
END THIRD-PARTY FILE 0ebee8a907a2d111

The third-party file has ended. Everything between the 0ebee8a907a2d111 tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 2938 of 4516 bytes. © mcollina · MIT · https://github.com/mcollina/skills/tree/HEAD/skills/typescript-magician/SKILL.md

_Part of the page did not fit — see the HTML version._

---
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
