en un clic
typescript
Must always be enabled when writing/reviewing TypeScript code.
Menu
Must always be enabled when writing/reviewing TypeScript code.
Core prompt engineering and context engineering best practices for Claude Code prompts.
Must always be enabled when writing/reviewing React code.
TypeScript project initialization best practices
Create documentation optimized for ADHD and neurodivergent readers with short scannable content, clear hierarchy, progressive disclosure, actionable steps, and reduced cognitive load. Use when creating or improving any technical documentation (README files, API docs, tutorials, guides, onboarding materials) or when users request accessible, easy-to-scan, or beginner-friendly documentation.
Expert guidance on building production-ready multi-agent AI systems using CrewAI, LangChain, AutoGen, and custom architectures. Use when building agent systems, selecting frameworks, designing multi-agent workflows, debugging agent behavior, or deploying agents to production.
Expert guidance for developing and integrating AI systems using LLM APIs, SDKs, and Model Context Protocol (MCP). Covers API selection, SDK patterns, MCP development, production patterns, security, cost optimization, and architecture decisions for building production-ready AI integrations.
| name | typescript |
| description | Must always be enabled when writing/reviewing TypeScript code. |
LLM-generated code faces inherent challenges with E2E testing and runtime verification. Compensate by maximizing compile-time verification through:
Goal: If it type-checks, it works. Shift as many bugs as possible from runtime to compile-time.
<type_assertions>
as Type Assertions are ProhibitedRationale: Type assertions bypass TypeScript's type system and introduce type unsoundness. They are frequently misused to silence legitimate type errors.
Policy:
as to resolve type errorsas any or as unknown as Xpath/to/file.ts:123 - requires manual review for potential as usage"Why you cannot judge appropriately: As an LLM, you lack the contextual understanding to determine if a type assertion is truly necessary vs. masking a real type error. When in doubt, preserve type safety.
Instead of as, address the underlying type issue:
if (typeof x === 'string'))<strict_typing>
as const satisfies Over Loose AnnotationsProblem with loose typing:
const config: Config = {
mode: 'development', // Type widened to string
port: 3000
}
// config.mode is string, not 'development' | 'production'
Solution - strict typing with as const satisfies:
const config = {
mode: 'development',
port: 3000
} as const satisfies Config
// config.mode is exactly 'development' (literal type preserved)
Benefits:
Application:
// ❌ Redundant annotation
const result: number = calculateTotal(items)
// ✅ Let TypeScript infer
const result = calculateTotal(items)
Use annotations when:
as const satisfies)<external_data>
any for External DataSources requiring validation:
JSON.parse() resultsCheck for generated type definitions first:
hono/client with type inferenceExample (Hono client):
import { hc } from 'hono/client'
import type { AppType } from './server'
const client = hc<AppType>('/api')
const response = await client.users.$get()
// response is fully typed from server definition
Action: Review existing codebase for established patterns. Most projects already have type-safe API layers.
When type generation is unavailable, use schema validation:
Preference order:
package.json)pnpm add valibot)Example (valibot):
import * as v from 'valibot'
const UserSchema = v.object({
id: v.number(),
name: v.string(),
role: v.union([v.literal('admin'), v.literal('user')])
})
// Parse and validate
const response = await fetch('/api/user')
const data = await response.json()
const user = v.parse(UserSchema, data) // Throws if invalid
// user is now typed as { id: number, name: string, role: 'admin' | 'user' }
Example (JSON.parse):
// ❌ Unsafe
const data = JSON.parse(localStorage.getItem('config')!)
// ✅ Validated
const raw = localStorage.getItem('config')
if (raw) {
const data = v.parse(ConfigSchema, JSON.parse(raw))
}
Even if "you know" the shape, external data can change:
Type safety = static types + runtime validation </external_data>
<best_practices>
Rule: Use arrow functions (=>) instead of function keyword for consistency and lexical scoping benefits.
Rationale:
this binding (no context confusion)// ❌ Function declaration
function calculateTotal(items: Item[]): number {
return items.reduce((sum, item) => sum + item.price, 0)
}
// ✅ Arrow function
const calculateTotal = (items: Item[]): number => {
return items.reduce((sum, item) => sum + item.price, 0)
}
// ✅ Concise form (single expression)
const calculateTotal = (items: Item[]): number =>
items.reduce((sum, item) => sum + item.price, 0)
Exception: When hoisting is genuinely required (rare), document the reason.
type LoadingState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: T }
| { status: 'error'; error: Error }
const render = (state: LoadingState<User>) => {
switch (state.status) {
case 'idle':
return 'Not started'
case 'loading':
return 'Loading...'
case 'success':
return state.data.name // data is available
case 'error':
return state.error.message // error is available
}
}
Benefits: Impossible to access data when status is 'error'.
const assertNever = (x: never): never => {
throw new Error(`Unexpected value: ${x}`)
}
switch (state.status) {
case 'idle':
case 'loading':
case 'success':
case 'error':
return
default:
assertNever(state) // Compile error if cases are missing
}
// ❌ Ambiguous state
type User = {
data?: UserData
error?: Error
}
// What if both are defined? Neither?
// ✅ Explicit state
type User =
| { status: 'success'; data: UserData }
| { status: 'error'; error: Error }
unknown Over any for Truly Unknown Types// ❌ Disables all type checking
const process = (data: any) => {
return data.foo.bar // No errors, runtime explosion
}
// ✅ Forces validation
const process = (data: unknown) => {
if (typeof data === 'object' && data !== null && 'foo' in data) {
// Narrow the type before use
}
}
// Prevent accidental mutations
type Config = {
readonly apiUrl: string
readonly timeout: number
}
// For arrays
const items = ['a', 'b'] as const
If type definitions become incomprehensible, simplify the design:
<error_handling>
If you encounter legitimate type errors you cannot fix without as:
// TODO: Type error at line X - potential TypeScript limitation
// Requires manual review before using type assertion
const result = someComplexOperation() // Type error here
src/module.ts:45 - escalated for review"Do not:
as assertionsany to bypass the error