| name | lang-typescript |
| description | Write clean, type-safe TypeScript code using modern patterns, strict configuration, and best practices. Use when writing TypeScript code, configuring projects, or solving type-related challenges. |
TypeScript Expert
Variables
Inputs
TYPESCRIPT_TASK: $ARGUMENTS (if provided) or current TypeScript task
Write clean, type-safe TypeScript code that leverages the full power of the type system to catch bugs at compile time for $TYPESCRIPT_TASK.
When to Use This Skill
Use this skill when:
- Writing or refactoring TypeScript code
- Configuring TypeScript projects (tsconfig.json)
- Solving complex type-related challenges
- Choosing between type system patterns
- Validating external data with types
Core Workflow
1. Type Decision Tree
Choose the right construct:
| Use Case | Use | Not |
|---|
| Object shapes | interface | type |
| Unions/primitives | type | interface |
| Dynamic data | unknown | any |
| State machines | Discriminated unions | Complex conditionals |
| Domain types | Branded types | Plain primitives |
Example:
interface User {
id: number;
name: string;
}
type Status = "idle" | "loading" | "success";
type USD = number & { readonly __brand: "USD" };
type User = { id: number };
interface Status {
}
2. State Modeling Pattern
For finite states, always use discriminated unions to eliminate impossible states:
type ApiState =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: string }
| { status: "error"; message: string };
function handle(state: ApiState) {
switch (state.status) {
case "success":
return state.data;
case "error":
return state.message;
case "idle":
return "Not started";
case "loading":
return "Loading...";
default:
const _exhaustive: never = state;
throw new Error("Unhandled state");
}
}
3. Validation Workflow
Always validate external data with runtime checks:
- Simple validation: Type guards
- Complex validation: Schema libraries (Zod, Yup)
function isUser(data: unknown): data is User {
return (
typeof data === "object" &&
data !== null &&
"id" in data &&
typeof (data as any).id === "number"
);
}
import { z } from "zod";
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email(),
});
type User = z.infer<typeof UserSchema>;
const user = UserSchema.parse(apiData);
Never use type assertions without validation:
const user = data as User;
if (isUser(data)) {
}
4. Configuration Checklist
For new projects, enable strict mode plus:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noPropertyAccessFromIndexSignature": true,
"moduleResolution": "bundler"
}
}
Why these matter:
noUncheckedIndexedAccess - Prevents undefined access bugs
exactOptionalPropertyTypes - Distinguishes missing from undefined
moduleResolution: "bundler" - Optimized for Vite/esbuild
5. Code Organization Rules
Barrel files: Avoid for internal code (75% faster builds)
export * from "./Button";
import { Button } from "@/components/Button";
Only use barrel files for:
- Library entry points
- Public APIs
- Small modules (<10 exports)
Quick Reference Patterns
Utility Types
type UserPreview = Pick<User, "id" | "name">;
type PublicUser = Omit<User, "email">;
type UpdateDto = Partial<User>;
type CompleteUser = Required<User>;
type ImmutableUser = Readonly<User>;
type UserType = ReturnType<typeof getUser>;
Error Handling
try {
} catch (err: unknown) {
if (err instanceof Error) {
}
}
type Result<T, E = Error> =
| { success: true; value: T }
| { success: false; error: E };
Readonly Patterns
const config: Readonly<Config> = {
};
const numbers: readonly number[] = [1, 2, 3];
const ROUTES = { home: "/" } as const;
When to Consult Detailed References
For comprehensive information on advanced patterns, configuration options, or specific features, read:
references/best-practices-2025.md - Full TypeScript best practices guide
The reference includes:
- Advanced type patterns (conditional types, mapped types, branded types)
- Complete tsconfig.json options
- Modern features (decorators, const type parameters)
- Common anti-patterns and solutions
Quality Checklist
Before completing TypeScript code: