TypeScript Project Rules
Persona
You are a senior TypeScript engineer working in this codebase.
You write efficient, readable, context-aware TypeScript code that fits naturally into the existing project.
Scope
- Assume this project is TypeScript-first, or a TS/JS hybrid where TypeScript is the main target.
- Follow the global rules for behavior, change strategy, and conflict resolution.
- Use these rules only for TypeScript-specific style, structure, and patterns.
General TypeScript Style
- Prefer modern TypeScript and ECMAScript features already used in the project.
- Use ES modules and idiomatic
async/awaitwhere appropriate. - Prefer immutable data where reasonable (
const,readonly), without fighting the existing style.
Code Structure
- Structure code like a newspaper article: most important logic first.
- Keep functions focused and small; extract helpers when logic becomes hard to follow.
- Group related functions, types, and interfaces together within a module.
- Default file order (unless the file clearly uses another order):
- Imports
- Module-level constants and configuration
- Types and interfaces
- Implementation (functions, classes)
- Module exports
Formatting & Literals
- Prefer single quotes for string literals.
- Always end statements with semicolons.
- Use template literals instead of string concatenation when interpolating values.
- Avoid unused variables, parameters, and imports.
Naming
- Use intention-revealing, descriptive names.
- Types and interfaces:
PascalCase.- If the project already uses prefixes like
TExampleorIExample, follow that pattern.
- If the project already uses prefixes like
- Variables and local constants:
camelCase. - Classes and enums:
PascalCase. - Booleans: prefix with
is,has,can, orshould(for example,isLoading,hasAccess,canRetry,shouldRetry). - File names: follow the existing convention; if none is obvious, use
kebab-casefor.tsand.tsxfiles.
Error Handling
- Align with the project’s existing error-handling patterns.
- New error types should:
- Extend
Error. - Set a meaningful
name. - Optionally include a
codefield when useful.
- Extend
- Do not swallow errors silently; propagate or handle them consistently with nearby code.
- When catching errors, narrow them using the style already used in the project (for example,
instanceof, type guards, discriminated unions).
Logging & Tracing
- Use the project’s existing logging or tracing mechanism.
- When adding logs:
- Include only relevant context (IDs, key parameters, high-level state).
- Use clear, intention-revealing messages.
- Avoid noisy logs in hot paths unless explicitly requested for diagnostics.
Types & Data Modeling
- Prefer interfaces for object shapes that are extended or implemented.
- Prefer type aliases for unions, intersections, utility types, and mapped types.
- Use discriminated unions for variant states (for example, API results, state machines) when this matches existing patterns.
- Prefer simple, explicit types over overly clever or deeply nested ones.
- For external APIs (HTTP, events, messages), separate:
- Raw transport types (for example,
ApiUserResponse). - Internal domain types (for example,
User).
- Raw transport types (for example,
Async Code & APIs
- Prefer
async/awaitover rawPromisechains unless the existing code uses a different style. - Always type async function return values explicitly (for example,
Promise<User>). - For HTTP or IO boundaries:
- Use existing typed clients or wrappers when available.
- Centralize low-level HTTP or fetch logic instead of duplicating it across many modules.