Master enterprise-grade TypeScript development with type-safe patterns, modern tooling, and framework integration. This skill provides comprehensive guidance for TypeScript 5.9+, covering type system fundamentals (generics, mapped types, conditional types, satisfies operator), enterprise patterns (error handling, validation with Zod), React integration for type-safe frontends, NestJS for scalable APIs, and LangChain.js for AI applications. Use when building type-safe applications, migrating JavaScript codebases, configuring modern toolchains (Vite 7, pnpm, ESLint, Vitest), implementing advanced type patterns, or comparing TypeScript with Java/Python approaches.
Master enterprise-grade TypeScript development with type-safe patterns, modern tooling, and framework integration. This skill provides comprehensive guidance for TypeScript 5.9+, covering type system fundamentals (generics, mapped types, conditional types, satisfies operator), enterprise patterns (error handling, validation with Zod), React integration for type-safe frontends, NestJS for scalable APIs, and LangChain.js for AI applications. Use when building type-safe applications, migrating JavaScript codebases, configuring modern toolchains (Vite 7, pnpm, ESLint, Vitest), implementing advanced type patterns, or comparing TypeScript with Java/Python approaches.
Building type-safe React, NestJS, or Node.js applications
Migrating JavaScript codebases to TypeScript
Implementing advanced type patterns (generics, mapped types, conditional types)
Configuring modern TypeScript toolchains (Vite, pnpm, ESLint)
Designing type-safe API contracts with Zod validation
Comparing TypeScript approaches with Java or Python
Project Setup Checklist
Before starting any TypeScript project:
- [ ] Use pnpm for package management (faster, disk-efficient)
- [ ] Configure ESM-first (type: "module" in package.json)
- [ ] Enable strict mode in tsconfig.json
- [ ] Set up ESLint with @typescript-eslint
- [ ] Add Prettier for consistent formatting
- [ ] Configure Vitest for testing
Type System Quick Reference
Primitive Types
constname: string = ;
: = ;
: = ;
: = ;
: = ();
"Alice"
const
age
number
30
const
active
boolean
true
const
id
bigint
9007199254740991n
const
key
symbol
Symbol
"unique"
Union and Intersection Types
// Union: value can be one of several typestypeStatus = "pending" | "approved" | "rejected";
// Intersection: value must satisfy all typestypeEmployee = Person & { employeeId: string };
// Discriminated union for type-safe handlingtypeResult<T> =
| { success: true; data: T }
| { success: false; error: string };
function handleResult<T>(result: Result<T>): T | null {
if (result.success) {
return result.data; // TypeScript knows data exists here
}
console.error(result.error);
returnnull;
}
Type Guards
// typeof guardfunctionprocess(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}
// Custom type guardinterfaceUser { type: "user"; name: string }
interfaceAdmin { type: "admin"; permissions: string[] }
functionisAdmin(person: User | Admin): person is Admin {
return person.type === "admin";
}
The satisfies Operator (TS 5.0+)
Validate type conformance while preserving inference:
// Problem: Type assertion loses specific type infoconst colors1 = {
red: "#ff0000",
green: "#00ff00"
} asRecord<string, string>;
colors1.red.toUpperCase(); // OK, but red could be undefined// Solution: satisfies preserves literal typesconst colors2 = {
red: "#ff0000",
green: "#00ff00"
} satisfiesRecord<string, string>;
colors2.red.toUpperCase(); // OK, and TypeScript knows red exists
Generics Patterns
Basic Generic Function
function first<T>(items: T[]): T | undefined {
return items[0];
}
const num = first([1, 2, 3]); // number | undefinedconst str = first(["a", "b"]); // string | undefined
Constrained Generics
interfaceHasLength {
length: number;
}
function logLength<T extendsHasLength>(item: T): T {
console.log(item.length);
return item;
}
logLength("hello"); // OK: string has lengthlogLength([1, 2, 3]); // OK: array has lengthlogLength(42); // Error: number has no length
Add allowJs: true and checkJs: false to tsconfig.json
Rename files from .js to .ts one at a time
Add type annotations gradually
Enable stricter options incrementally
JSDoc for Gradual Typing
// Before full migration, use JSDoc/**
* @param {string} name
* @param {number} age
* @returns {User}
*/functioncreateUser(name, age) {
return { name, age };
}