balligh-insage/claida-typescript-rules icon
public
Published on 3/6/2025
TypeScript Rules

Rules
claida-typescript-rules
- Focus on **type safety**, clarity, and maintainability.
- Favor **functional programming** techniques (pure functions, small composable utilities).
- Use **strict TypeScript** (no `any`, minimal `unknown`, prefer discriminated unions over type casts).
- Offer **concise** and **technically accurate** solutions, with short code snippets where beneficial.
- Keep code examples minimal, well-typed, and aligned with advanced TypeScript patterns (generics, union narrowing, branding, etc.).
- Use **kebab-case** for directories and files (e.g., `my-utility.ts`).
- Use **camelCase** for variables and functions (e.g., `fetchData`, `isValidUser`).
- Name boolean variables with verbs like `is`, `can`, `has`, or `should`.
- Prefer interfaces for **objects** and **types** for **unions or mapped types**.
- Keep each **type or interface** definition minimal and purposeful.
- Use **generics** to enforce correctness in function or component signatures.
- Use **arrow functions** for short utilities or inline callbacks.
- For complex logic, define named functions to keep code discoverable.
- Never use `any`. Use **`unknown`** if an absolutely unconstrained type is required, and then narrow it.
- Always attempt **type narrowing** or **discriminated unions**.
- Use **JSDoc** for exported functions or complex types.
- Embrace union types (e.g. `string | number`) and **narrow** them with `if (typeof val === 'string') { ... }`.
- Discriminated unions: use a literal property (like `type: 'loading' | 'success' | 'error'`) for clear narrowing blocks.
- For flexible data shapes, wrap them in `<T>` generics.
- Constrain generics (`<T extends object>`) to maintain correctness.
- Use `as const` for immutable data or literal inferences.
- For advanced runtime checks, define **assertion** or **predicate** functions.
- For advanced transformations, use `extends`, `infer`, and `keyof` responsibly.
- Use template literal types for creating **dynamic string** types or route definitions.
- Use **Zod** or similar schema libraries for runtime validation, refining to strong TS types.
- Distinguish logically unique strings with branding/nominal types.
- For multi-step flows or complex conditions, define **discriminated unions** representing each state.
- Keep each function under ~20 lines, focusing on a single task. If it grows, refactor to smaller utilities.
- For fetch or external calls, wrap results in typed functions or custom hooks, ensuring strict input/output shapes.
- Detect invalid branches early with exhaustive checks.
- Avoid unguarded type assertions (as SomeType) unless absolutely certain.
- Keep strictNullChecks on, handle null/undefined explicitly.
- Use ESLint + TypeScript rules to enforce consistent style, naming, no unused vars.
- Consider Prettier for consistent formatting.
- Test each type-level utility and data transformation with frameworks like Jest.