TypeScript Best Practices
Priority: P1 (OPERATIONAL)
Implementation Guidelines
- Naming: Use
PascalCasefor Classes/Types/Interfaces,camelCasefor variables/functions, andUPPER_SNAKEfor static constants. - Functions: Use
arrow functionsfor callbacks/logic;function declarationfor top-level exports. Always typepublic APIreturns. - Modules: Use
Named exportsONLY to enable better refactoring/auto-imports. - Async: Use
async/awaitwithPromise.all()for parallel execution. Implementtry-catchfor error handling; typecatch(e) as unknownand narrow before use. Avoid.then().catch()chains. - Classes: Explicitly use
private,protected, andpublicmodifiers. Favorcompositionover inheritance anddependency injectionwithconstructor injectionand interfaces over singletons for testability. - Type Safety: Use
neverfor exhaustiveness checks in switch-cases. - Optional: Use
optional chaining(?.) andnullish coalescing(??) over manual checks. - Imports: Enforce
external packages → internal modules → relative importsorder automatically viaeslint-plugin-import. Useimport typefor interfaces/types to ensure better tree-shaking and zero runtime overhead. - Validation: Use
ZodorTsoafor runtime boundary validation.
Anti-Patterns
- No Default Exports: Use named exports.
- No Implicit Returns: Specify return types.
- No Unused Variables: Enable
noUnusedLocals. - No
require: Use ES6import. - No Empty Interfaces: Use
typeor non-empty interface. - No
any: Useunknownor a specific type. - No Unsafe Mocks: Cast with
jest.Mocked<T>oras unknown as T. - No eslint-disable: Fix root cause; never suppress warnings.
References
See references/examples.md for Immutable Interfaces, Exhaustiveness Checking, Assertion Functions, DI Patterns, and Import Organization.