--- name: phoenix-typescript description: TypeScript conventions and patterns for any TypeScript code in the Phoenix monorepo — including js/packages/, app/, and any other TS directories. Use this skill whenever writing, reviewing, or modifying TypeScript code — new functions, types, exports, tests, or refactors. Also trigger when the user asks about TS patterns, naming conventions, or best practices for this project. metadata: internal: true --- # Phoenix TypeScript Conventions These conventions apply to **all** TypeScript in the Phoenix monorepo — the `app/` frontend, the `js/packages/` libraries (phoenix-client, phoenix-cli, phoenix-evals, phoenix-mcp, phoenix-otel, phoenix-config), examples, and benchmarks. Before writing new code, explore the directory you're working in to understand existing patterns — then follow these rules. ## Naming Self-documenting names eliminate mental parsing for the next reader. - Variables must not use single letters — even loop counters benefit from `index`, `row`, `char`. - Complex conditions should be extracted into named booleans so code reads as prose. - Booleans must use verb prefixes: `isAllowed`, `hasError`, `canSubmit` — not `allowed`, `error`. - Function names must start with an action verb that describes what the function does: `getUser`, `normalizeTimestamp`, `logEvent`, `parseResponse`, `buildQuery` — not `user()`, `timestamp()`, `event()`. ```ts // Bad — single letters and ambiguous names for (let i = 0; i < s.length; i++) { const d = s[i].ts - s[i - 1]?.ts; const r = fn(s[i].v); } // Good — self-documenting for (let index = 0; index < spans.length; index++) { const elapsed = spans[index].timestamp - spans[index - 1]?.timestamp; const result = normalizeValue(spans[index].value); } // Bad — boolean without verb prefix, condition inline