Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
0xbigboss avatar

Typescript Best Practices

  • 3k installs
  • 52 repo stars
  • Updated June 24, 2026
  • 0xbigboss/claude-code

typescript-best-practices is an agent skill that enforces type-first TypeScript patterns, illegal-state prevention, and Zod runtime validation for ts and js files.

About

typescript-best-practices is an agent skill for TypeScript and JavaScript files covering type-first patterns, functional style, and runtime validation aligned with project CLAUDE.md conventions. It pairs with react-best-practices whenever work touches React components, tsx files, or React imports because this skill covers language fundamentals only. Core patterns make illegal states unrepresentable through discriminated unions instead of overlapping boolean flags, branded types for domain primitives like UserId, const assertions for literal role unions, and exhaustive switch checks with never. Runtime validation guidance centers on Zod schemas as the single source of truth with z.infer types, safeParse for user input, parse at trust boundaries, schema composition via extend pick omit merge, and transform for normalization at parse time. Optional type-fest utilities include Opaque for branded types, PartialDeep, ReadonlyDeep, SetRequired, SetOptional, and Simplify for complex intersections. Developers reach for it when reading or writing ts, tsx, js files or tsconfig.json and need compile-time safety plus Zod validation patterns aligned with repository standards.

  • Pairs with react-best-practices for tsx work because this skill covers TypeScript language idioms only.
  • Discriminated unions, branded types, const assertions, and never-checked exhaustive switches prevent invalid states.
  • Zod schemas are the single source of truth with safeParse for forms and parse at API trust boundaries.
  • Documents optional type-fest helpers such as Opaque, PartialDeep, and Simplify for advanced typing.
  • Triggers on any TypeScript or JavaScript file work including tsconfig.json changes.

Typescript Best Practices by the numbers

  • 3,008 all-time installs (skills.sh)
  • +41 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #59 of 1,352 Code Review & Quality skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
At a glance

typescript-best-practices capabilities & compatibility

Capabilities
discriminated union state modeling · branded domain primitive types · zod schema single source of truth patterns · exhaustive switch never checks · optional type fest advanced utilities
Use cases
refactoring · api development
From the docs

What typescript-best-practices says it does

Use the type system to prevent invalid states at compile time.
SKILL.md
Define schemas as single source of truth; infer TypeScript types with `z.infer<>`.
SKILL.md
When working with React components (`.tsx`, `.jsx` files or `@react` imports), always load `react-best-practices` alongside this skill.
SKILL.md
npx skills add https://github.com/0xbigboss/claude-code --skill typescript-best-practices

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs3k
repo stars52
Security audit3 / 3 scanners passed
Last updatedJune 24, 2026
Repository0xbigboss/claude-code

How do I write TypeScript that prevents invalid states at compile time and validates external data with Zod?

Apply type-first TypeScript patterns, discriminated unions, branded types, exhaustive switches, and Zod runtime validation.

Who is it for?

Developers editing TypeScript or JavaScript who need compile-time safety and Zod validation at trust boundaries.

Skip if: Skip for pure React component design patterns; load react-best-practices alongside this skill for tsx and hook work.

When should I use this skill?

User reads or writes .ts, .tsx, .js files or tsconfig.json and needs type-safe patterns or Zod validation.

What you get

Discriminated unions, branded types, exhaustive switches, and Zod schemas applied consistently across TypeScript and JavaScript edits.

  • Convention-aligned TypeScript and JavaScript edits

Files

SKILL.mdMarkdownGitHub ↗

TypeScript Best Practices

Follows type-first, functional, and error handling patterns from CLAUDE.md. This skill covers language-specific idioms only.

Pair with React Best Practices

When working with React components (.tsx, .jsx files or @react imports), always load react-best-practices alongside this skill. This skill covers TypeScript fundamentals; React-specific patterns (effects, hooks, refs, component design) are in the dedicated React skill.

Make Illegal States Unrepresentable

Use the type system to prevent invalid states at compile time.

Discriminated unions for mutually exclusive states:

// Good: only valid combinations possible
type RequestState<T> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error'; error: Error };

// Bad: allows invalid combinations like { loading: true, error: Error }
type RequestState<T> = {
  loading: boolean;
  data?: T;
  error?: Error;
};

Branded types for domain primitives:

type UserId = string & { readonly __brand: 'UserId' };
type OrderId = string & { readonly __brand: 'OrderId' };

// Compiler prevents passing OrderId where UserId expected
function getUser(id: UserId): Promise<User> { /* ... */ }

Const assertions for literal unions:

const ROLES = ['admin', 'user', 'guest'] as const;
type Role = typeof ROLES[number]; // 'admin' | 'user' | 'guest'

// Array and type stay in sync automatically
function isValidRole(role: string): role is Role {
  return ROLES.includes(role as Role);
}

Exhaustive switch with never check:

type Status = "active" | "inactive";

function processStatus(status: Status): string {
  switch (status) {
    case "active":
      return "processing";
    case "inactive":
      return "skipped";
    default: {
      const _exhaustive: never = status;
      throw new Error(`unhandled status: ${_exhaustive}`);
    }
  }
}

Runtime Validation with Zod

  • Define schemas as single source of truth; infer TypeScript types with z.infer<>. Avoid duplicating types and schemas.
  • Use safeParse for user input where failure is expected; use parse at trust boundaries where invalid data is a bug.
  • Compose schemas with .extend(), .pick(), .omit(), .merge() for DRY definitions.
  • Add .transform() for data normalization at parse time (trim strings, parse dates).
import { z } from "zod";

const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string().min(1),
  createdAt: z.string().transform((s) => new Date(s)),
});

type User = z.infer<typeof UserSchema>;

// Strict parsing at trust boundaries — throws if API contract violated
export async function fetchUser(id: string): Promise<User> {
  const response = await fetch(`/api/users/${id}`);
  if (!response.ok) {
    throw new Error(`fetch user ${id} failed: ${response.status}`);
  }
  return UserSchema.parse(await response.json());
}

// Caller handles both success and error from user input
const result = UserSchema.safeParse(formData);
if (!result.success) {
  setErrors(result.error.flatten().fieldErrors);
  return;
}

Optional: type-fest

For advanced type utilities beyond TypeScript builtins, consider type-fest:

  • Opaque<T, Token> - cleaner branded types than manual & { __brand } pattern
  • PartialDeep<T> - recursive partial for nested objects
  • ReadonlyDeep<T> - recursive readonly for immutable data
  • SetRequired<T, K> / SetOptional<T, K> - targeted field modifications
  • Simplify<T> - flatten complex intersection types in IDE tooltips
import type { Opaque, PartialDeep } from 'type-fest';

type UserId = Opaque<string, 'UserId'>;
type UserPatch = PartialDeep<User>;

Related skills

How it compares

Pick typescript-best-practices over generic linting skills when agents need repo-specific type-first and functional idioms rather than only ESLint rule fixes.

FAQ

When should I load react-best-practices too?

Always when working with React components, tsx or jsx files, or @react imports because this skill covers TypeScript fundamentals only.

When should I use Zod safeParse versus parse?

Use safeParse for user input where failure is expected; use parse at trust boundaries where invalid data indicates a bug.

Code Review & Qualitybackendfrontend

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.