🎯

writing-typescript

🎯Skill

from alexei-led/claude-code-config

VibeIndex|
What it does

Guides TypeScript development with strict typing, discriminated unions, flat control flow, and modern best practices for robust, type-safe code.

πŸ“¦

Part of

alexei-led/claude-code-config(15 items)

writing-typescript

Installation

BunRun with Bun
bun install # Install deps
BunRun with Bun
bun run build # Build
BunRun with Bun
bun run lint # Lint
BunRun with Bun
bun run format # Format
πŸ“– Extracted from docs: alexei-led/claude-code-config
3Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Idiomatic TypeScript development. Use when writing TypeScript code, Node.js services, React apps, or discussing TS patterns. Emphasizes strict typing, composition, and modern tooling (bun/vite).

Overview

# TypeScript Development (5.x)

Core Philosophy

  1. Strict Mode Always

- Enable all strict checks in tsconfig

- Treat any as a bugβ€”use unknown for untrusted input

- noUncheckedIndexedAccess, exactOptionalPropertyTypes

  1. Interface vs Type

- interface for object shapes (extensible, mergeable)

- type for unions, intersections, mapped types

- interface for React props and public APIs

  1. Discriminated Unions

- Literal kind/type tag for variants

- Exhaustive switch with never check

- Model states as unions, not boolean flags

  1. Flat Control Flow

- Guard clauses with early returns

- Type guards and predicate helpers

- Maximum 2 levels of nesting

  1. Result Type Pattern

- Result for explicit error handling

- Discriminated union for success/failure

- Custom Error subclasses for instanceof

Quick Patterns

Discriminated Unions (Not Boolean Flags)

```typescript

// GOOD: discriminated union for state

type LoadState =

| { status: "idle" }

| { status: "loading" }

| { status: "success"; data: T }

| { status: "error"; error: string };

// BAD: boolean flags

type LoadState = {

isLoading: boolean;

isError: boolean;

data: T | null;

error: string | null;

};

```

Flat Control Flow (No Nesting)

```typescript

// GOOD: guard clauses, early returns

function process(user: User | null): Result {

if (!user) return err("no user");

if (!user.isActive) return err("inactive");

if (user.role !== "admin") return err("not admin");

return ok(doWork(user)); // happy path at end

}

// BAD: nested conditions

function process(user: User | null): Result {

if (user) {

if (user.isActive) {

if (user.role === "admin") {

return ok(doWork(user));

}

}

}

return err("invalid");

}

```

Type Guards

```typescript

function isUser(value: unknown): value is User {

return (

typeof value === "object" &&

value !== null &&

"id" in value &&

"name" in value

);

}

// Predicate helper for flat code

const isActiveAdmin = (u: User | null): u is User & { role: "admin" } =>

!!u && u.isActive && u.role === "admin";

```

Result Type

```typescript

type Result = { ok: true; value: T } | { ok: false; error: E };

const ok = (value: T): Result => ({ ok: true, value });

const err = (error: E): Result => ({ ok: false, error });

async function fetchUser(

id: string,

): Promise> {

try {

const res = await fetch(/users/${id});

if (res.status === 404) return err("not-found");

if (!res.ok) return err("network");

return ok(await res.json());

} catch {

return err("network");

}

}

```

Exhaustive Switch

```typescript

function area(shape: Shape): number {

switch (shape.kind) {

case "circle":

return Math.PI shape.radius * 2;

case "square":

return shape.size ** 2;

case "rect":

return shape.width * shape.height;

default: {

const _exhaustive: never = shape; // Error if variant missed

return _exhaustive;

}

}

}

```

tsconfig.json Essentials

```json

{

"compilerOptions": {

"target": "ES2022",

"module": "ESNext",

"moduleResolution": "bundler",

"strict": true,

"noUncheckedIndexedAccess": true,

"exactOptionalPropertyTypes": true,

"noImplicitReturns": true,

"noImplicitOverride": true,

"isolatedModules": true

}

}

```

References

  • [PATTERNS.md](PATTERNS.md) - Code patterns and style
  • [REACT.md](REACT.md) - React component patterns
  • [TESTING.md](TESTING.md) - Testing with vitest

Commands

```bash

bun install # Install deps

bun run build # Build

bun test # Test

bun run lint # Lint

bun run format # Format

```