.cursorrules (deprecated)
rules/typescript-strict/.cursorrules.cursorrules
Quality
65/100
Scores the file, not the repository.Length
1,055 words
15 headings · 17 code blocksRepository
16
— · pushed 109 days agoLast changed
2 days ago
First indexed 2 days ago.1# Strict TypeScript — Cursor Rules2# Zero-compromise TypeScript: no any, proper generics, exhaustive type safety34# Project Context5You are writing strict TypeScript. The project has all strict compiler options enabled.6Every value is typed. Every edge case is handled. The type system is your primary tool7for preventing bugs at compile time rather than catching them at runtime.89# tsconfig.json Strict Settings (Required)10```json11{12 "compilerOptions": {13 "strict": true,14 "noUncheckedIndexedAccess": true,15 "exactOptionalPropertyTypes": true,16 "noImplicitReturns": true,17 "noFallthroughCasesInSwitch": true,18 "noPropertyAccessFromIndexSignature": true,19 "forceConsistentCasingInFileNames": true20 }21}22```2324# The "No Any" Rule25- NEVER use `any`. There is always a better type.26- Use `unknown` when you don't know the type — then narrow it:27```typescript28 function processInput(input: unknown): string {29 if (typeof input === 'string') return input;30 if (typeof input === 'number') return String(input);31 throw new TypeError(`Unexpected input type: ${typeof input}`);32 }33```34- Use `Record<string, unknown>` instead of `object` or `any` for generic objects.35- For JSON parsing: `JSON.parse(text) as unknown`, then validate with zod or manual narrowing.36- For third-party libraries without types: create a `.d.ts` declaration file, don't use `any`.3738# Type Narrowing Patterns39- Use discriminated unions for state machines and variant types:40```typescript41 type Result<T> =42 | { success: true; data: T }43 | { success: false; error: Error };44```45- Create type guard functions for complex runtime checks:46```typescript47 function isUser(value: unknown): value is User {48 return typeof value === 'object' && value !== null49 && 'id' in value && typeof (value as Record<string, unknown>).id === 'string';50 }51```52- Use `satisfies` operator to validate types while preserving literal inference:53```typescript54 const config = {55 port: 3000,56 host: 'localhost',57 } satisfies ServerConfig;58 // config.port is `3000` (literal), not just `number`59```60- Use `asserts` for assertion functions that narrow in the calling scope:61```typescript62 function assertDefined<T>(value: T | undefined, name: string): asserts value is T {63 if (value === undefined) throw new Error(`${name} is required`);64 }65```6667# Generic Patterns68- Constrain generics with `extends` to prevent misuse:69```typescript70 function getProperty<T extends object, K extends keyof T>(obj: T, key: K): T[K] {71 return obj[key];72 }73```74- Use default generic parameters for convenience:75```typescript76 type ApiResponse<T = void> = { status: number; data: T; timestamp: Date };77```78- Use `infer` in conditional types to extract nested types:79```typescript80 type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;81 type ArrayElement<T> = T extends readonly (infer E)[] ? E : never;82```83- Use mapped types to transform existing types:84```typescript85 type Nullable<T> = { [K in keyof T]: T[K] | null };86 type ReadonlyDeep<T> = { readonly [K in keyof T]: ReadonlyDeep<T[K]> };87```8889# Utility Type Usage90- `Partial<T>` — for update DTOs where all fields are optional.91- `Required<T>` — to ensure all optional fields are present.92- `Pick<T, K>` — to create subsets of types for specific use cases.93- `Omit<T, K>` — to exclude fields (careful: doesn't error on non-existent keys).94- `Record<K, V>` — for typed dictionaries and maps.95- `Extract<T, U>` / `Exclude<T, U>` — for union type manipulation.96- `NonNullable<T>` — to strip null and undefined from types.97- `ReturnType<T>` / `Parameters<T>` — to extract function signatures.98- Prefer creating named types over deeply nested utility type compositions.99100# Enum Alternatives101- Prefer `as const` objects over TypeScript enums:102```typescript103 const Status = { Active: 'active', Inactive: 'inactive', Pending: 'pending' } as const;104 type Status = typeof Status[keyof typeof Status]; // 'active' | 'inactive' | 'pending'105```106- Benefits: tree-shakeable, no runtime cost, works with string literals.107- Use string literal unions for simple cases: `type Direction = 'up' | 'down' | 'left' | 'right'`.108109# Exhaustive Checks110- Always handle all cases in discriminated unions:111```typescript112 function assertNever(value: never): never {113 throw new Error(`Unhandled case: ${JSON.stringify(value)}`);114 }115116 switch (action.type) {117 case 'increment': return state + 1;118 case 'decrement': return state - 1;119 default: return assertNever(action); // compile error if a case is missed120 }121```122- This pattern ensures adding a new variant to a union forces handling everywhere it's used.123124# Function Patterns125- Use function overloads for APIs with multiple call signatures:126```typescript127 function createElement(tag: 'a'): HTMLAnchorElement;128 function createElement(tag: 'canvas'): HTMLCanvasElement;129 function createElement(tag: string): HTMLElement;130 function createElement(tag: string): HTMLElement { ... }131```132- Use parameter objects for functions with 3+ parameters:133```typescript134 function createUser(options: { name: string; email: string; role?: Role }): User135```136- Type callbacks explicitly — don't rely on contextual typing for exported APIs.137- Use `readonly` arrays in function parameters when you don't mutate them.138139# Object and Array Patterns140- Use `readonly` on arrays and objects that shouldn't be mutated:141```typescript142 function processItems(items: readonly Item[]): Summary { ... }143```144- Use `as const` for literal tuples: `const pair = [1, 'hello'] as const; // [1, 'hello']`145- Use `Map<K, V>` and `Set<T>` instead of objects for dynamic key-value storage.146- Access index signatures safely with `noUncheckedIndexedAccess`:147```typescript148 const map: Record<string, number> = { a: 1 };149 const value = map['b']; // type is `number | undefined`, not `number`150```151152# Module Patterns153- Use barrel exports (index.ts) carefully — they can hurt tree-shaking and cause circular deps.154- Export types separately: `export type { User, UserCreate }` (transpiled away, no runtime cost).155- Use `import type` when importing only types: `import type { Config } from './config'`.156157# Error Handling158- Type errors explicitly — avoid `catch (e: any)`:159```typescript160 try { ... } catch (error) {161 if (error instanceof NetworkError) { /* handle */ }162 if (error instanceof ValidationError) { /* handle */ }163 throw error; // re-throw unexpected errors164 }165```166- Create typed error classes with additional context fields.167- Use Result types for expected errors instead of throwing.168169# Common Mistakes to Avoid170- DON'T: Use `any` — use `unknown`, proper types, or generics.171- DON'T: Use non-null assertion `!` without a guard — it suppresses real bugs.172- DON'T: Use type assertions `as T` to silence errors — fix the actual type mismatch.173- DON'T: Use `// @ts-ignore` — use `// @ts-expect-error` (fails when error is fixed, keeping code clean).174- DON'T: Use `Object`, `Function`, `String`, `Number`, `Boolean` — use lowercase primitives.175- DON'T: Return `undefined` implicitly — be explicit: `return undefined;`.176- DON'T: Use `==` or `!=` — always use `===` and `!==`.177
Also in survivorforge/cursor-rules
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| survivorforge/cursor-rulesrules/ai-ml-python/.cursorrules · 16 | .cursorrules | teststylearchdeployment+2 | 81/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/api-design-rest/.cursorrules · 16 | .cursorrules | lint-formatstylesecurityapi+3 | 69/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/api-microservices/.cursorrules · 16 | .cursorrules | buildteststylearch+5 | 92/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/aws-serverless/.cursorrules · 16 | .cursorrules | teststylearchtypes+6 | 73/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/chrome-extension/.cursorrules · 16 | .cursorrules | teststylearchtesting-strategy+4 | 81/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/clean-code/.cursorrules · 16 | .cursorrules | styledo-notagent-behaviourdocs | 57/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/database-sql/.cursorrules · 16 | .cursorrules | styletypessecuritydatabase+3 | 65/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/devops-docker/.cursorrules · 16 | .cursorrules | setupbuildteststyle+4 | 93/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/devops-infrastructure/.cursorrules · 16 | .cursorrules | buildteststylesecurity+3 | 93/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/django-rest/.cursorrules · 16 | .cursorrules | buildteststylearch+5 | 84/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/docker-devops/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 85/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/flutter-dart/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 89/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/fullstack-nextjs-prisma/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 96/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/go-gin/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+5 | 84/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/go-production/.cursorrules · 16 | .cursorrules | teststylearchtesting-strategy+3 | 89/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/golang-api/.cursorrules · 16 | .cursorrules | buildteststylearch+6 | 84/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/langchain-ai/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+4 | 84/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/mcp-server/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+7 | 68/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/mern-stack/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 81/100 | 2 days ago | |
| survivorforge/cursor-rulesrules/mobile-react-native/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 89/100 | 2 days ago |
Diff against rules/ai-ml-python/.cursorrules Diff against rules/api-design-rest/.cursorrules Diff against rules/api-microservices/.cursorrules Diff against rules/aws-serverless/.cursorrules Diff against rules/chrome-extension/.cursorrules Diff against rules/clean-code/.cursorrules Diff against rules/database-sql/.cursorrules Diff against rules/devops-docker/.cursorrules Diff against rules/devops-infrastructure/.cursorrules Diff against rules/django-rest/.cursorrules Diff against rules/docker-devops/.cursorrules Diff against rules/flutter-dart/.cursorrules Diff against rules/fullstack-nextjs-prisma/.cursorrules Diff against rules/go-gin/.cursorrules Diff against rules/go-production/.cursorrules Diff against rules/golang-api/.cursorrules Diff against rules/langchain-ai/.cursorrules Diff against rules/mcp-server/.cursorrules Diff against rules/mern-stack/.cursorrules Diff against rules/mobile-react-native/.cursorrules
