How do you implement TypeScript best practices for large-scale applications?
TypeScript provides type safety that catches errors at compile time rather than runtime. Configuration: use strict mode (strict: true in tsconfig.json) which enables all strict type checking options, target modern JavaScript (ES2020+) and use appropriate module system (ESNext for Vite projects). Type design: prefer interfaces for object shapes (extendable via declaration merging), use type aliases for unions, intersections, and mapped types, define types close to where they're used (colocate type definitions with their consumers), and export types from a central types directory for shared definitions. Utility types: Partial (all properties optional), Required (all required), Pick (subset of properties), Omit (exclude properties), Record (object with known key type), and ReturnType (infer function return type). Best practices: avoid type assertions (as) when possible (use type guards instead), never use any (use unknown for truly unknown types and narrow with type guards), use discriminated unions for state management (type State = { status: "loading" } { status: "success", data: User } { status: "error", error: Error }), and implement branded types for domain primitives (type UserId = string & { brand: "UserId" }). Generics: use generics for reusable components and utilities, constrain generics with extends for type safety (function getProperty (obj: T, key: K): T[K]), and use default generic parameters for common cases. React patterns: type component props with interfaces, use React.FC sparingly (prefer explicit return types), implement generic components for reusable UI (Table, List ), and type hooks properly (useReducer with discriminated union actions). Error handling: use Result/Either pattern for type-safe error handling, type error boundaries properly, and implement exhaustive switch checks using never type for discriminated unions.