typescript-style

A set of conventions for writing clearer TypeScript code, covering names, types, control flow, and comments. TypeScript is JavaScript with checks that catch many mistakes before the code runs.

In plain words
What is it for?
Use it when adding or reviewing TypeScript files, especially when a project has no established conventions. It gives examples for booleans, constants, type aliases, interfaces, and functions.
Why use it?
It reduces inconsistent naming and typing choices, making code easier to read, review, and maintain across a project.

Cursor rule

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add rules/tonyghiani/ai-essentials/typescript-style
Clone the repo
git clone --depth 1 https://github.com/tonyghiani/ai-essentials
Per session 0 Nothing until a file matches its globs; then the whole rule loads.
When invoked 831 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00000 $0.00831
Opus 5 $0.00000 $0.00415
Sonnet 5 $0.00000 $0.00166
Haiku 4.5 $0.00000 $0.00083

Measured 2d ago against content hash 7af86402e5f9, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

typescript-style scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

rules/typescript-style.mdc · 77 lines

How it starts

The opening of the file, as written. The whole thing — 77 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Project conventions win. Read the neighbouring files first; apply these where a project has no established convention of its own.

Naming

❌ const d = users.filter(u => u.active) ❌ const rc = clientMock() ✅ const activeUsers = users.filter((user) => user.active) ✅ const rulesClient = clientMock() ❌ const disabled = !status ❌ const refetchInterval = 30000 ✅ const isDisabled = !status ✅ const REFETCH_INTERVAL_MS = 30_000

is/has for state, should/can for intent. assert* throws, get* is cheap and sync, fetch* hits the network, resolve* is multi-step, create*/make* is a factory. Props take onX, the internal handler takes handleX.

Types

❌ enum Reason { License = 'license' } ✅ type TReason = 'license' | 'pricing_tier' ✅ const REASONS = ['license', 'pricing_tier'] as const // only when the runtime list is needed type TReason = (typeof REASONS)[number]

✅ interface IChecklist {} type TChecklistSlug = string I on interfaces, T on type aliases. Reach for interface wherever it can substitute a type.

❌ const entry = value as MemoryEntry ✅ function isMemoryEntry(value: unknown): value is IMemoryEntry {} any is banned, tests included. @ts-expect-error needs an inline reason; @ts-ignore never.

❌ if (reason === 'license') {} else if (reason === 'pricing_tier') {} ✅ const MESSAGES: Record<TReason, () => string> = { license: () => '', pricing_tier: () => '' } // Keying by reason makes this exhaustive: TypeScript errors if a reason lacks a message.

Explicit return types on exported server functions, factories, route handlers, and hooks returning a wide or nullable object. Inferred elsewhere. Generics only where they remove an unsafe cast. null means explicitly absent; undefined means not provided.

Control flow

❌ for (let i = 0; i < items.length; i++) { ids.push(items[i].id) } ✅ const ids = items.map((item) => item.id) Declarative by default. An imperative loop is a performance escape hatch; say why in a comment.

Read the full file on GitHub · 77 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 77 lines · 0 tokens per session scan A 7af86402e5f9

Subscribe to this mod's changes

typescript-style is a cursor rule published in the GitHub repository tonyghiani/ai-essentials (6 stars, last pushed 24d ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 831 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.