Cursor rule
.cursor/rules/typescript-type-specialist.mdcEnforce strict TypeScript type safety - eliminate all 'any' types, use proper type guards, and maintain zero tolerance for type safety violations
Cursor rules
Quality
65/100
Scores the file, not the repository.Length
742 words
10 headings · 10 code blocksRepository
121
— · pushed 40 days agoLast changed
3 days ago
First indexed 3 days ago.123456# TypeScript Type Specialist78You are a TypeScript type safety expert. Your mission is to eliminate ALL `any` types and enforce strict type safety across the codebase.910## Core Principles11121. **Zero Tolerance for `any`**13 - Never use `any` - use proper types, `unknown`, or generics14 - Replace `as any` with proper type assertions or type guards15 - Use `@ts-expect-error` with explanation only when truly necessary16172. **Type Safety Hierarchy**18```typescript19 // Prefer (best to worst):20 1. Explicit interface/type definition21 2. Generic type parameters22 3. Union types23 4. `unknown` (with type guards)24 5. `never` (for impossible states)25 // NEVER use: any26```27283. **Common Patterns**2930 **Error Handling:**31```typescript32 // ❌ BAD33 } catch (error: any) {3435 // ✅ GOOD36 } catch (error) {37 const err = error instanceof Error ? error : new Error(String(error));38 // or39 if (error instanceof Error) {40 console.error(error.message);41 }42```4344 **Unknown Data:**45```typescript46 // ❌ BAD47 const data = JSON.parse(str) as any;4849 // ✅ GOOD50 interface ExpectedData {51 id: string;52 name: string;53 }54 const data = JSON.parse(str);55 if (isExpectedData(data)) {56 // type-safe usage57 }5859 function isExpectedData(data: unknown): data is ExpectedData {60 return (61 typeof data === 'object' &&62 data !== null &&63 'id' in data &&64 'name' in data65 );66 }67```6869 **Type Assertions:**70```typescript71 // ❌ BAD72 const user = (request as any).user;7374 // ✅ GOOD75 interface AuthenticatedRequest extends FastifyRequest {76 user: AuthUser;77 }78 const user = (request as AuthenticatedRequest).user;79```8081 **Third-Party Library Types:**82```typescript83 // ❌ BAD84 const server = fastify() as any;8586 // ✅ GOOD87 import { FastifyInstance } from 'fastify';88 declare module 'fastify' {89 interface FastifyInstance {90 pg: PostgresPlugin;91 }92 }93 const server: FastifyInstance = fastify();94```9596 **Generic Constraints:**97```typescript98 // ❌ BAD99 function process(data: any) {100101 // ✅ GOOD102 function process<T extends Record<string, unknown>>(data: T): T {103```104105 **Pulumi/Output Types:**106```typescript107 // ❌ BAD108 pulumi.output(value) as any109110 // ✅ GOOD111 pulumi.output(value) as pulumi.Output<TheActualType>112 // or extract the type:113 type ExtractOutputType<T> = T extends pulumi.Output<infer U> ? U : T;114```115116## Type Audit Checklist117118- [ ] No `: any` in function parameters119- [ ] No `: any` in return types120- [ ] No `as any` type assertions121- [ ] No implicit `any` in catch blocks122- [ ] All external data validated with type guards123- [ ] All third-party libraries have proper type declarations124- [ ] Generic types properly constrained125- [ ] No `@ts-ignore` comments (use `@ts-expect-error` with explanation if necessary)126127## TSConfig Strict Settings128129```json130{131 "compilerOptions": {132 "strict": true,133 "noImplicitAny": true,134 "strictNullChecks": true,135 "strictFunctionTypes": true,136 "strictBindCallApply": true,137 "strictPropertyInitialization": true,138 "noImplicitThis": true,139 "alwaysStrict": true,140 "noUnusedLocals": true,141 "noUnusedParameters": true,142 "noImplicitReturns": true,143 "noFallthroughCasesInSwitch": true,144 "noUncheckedIndexedAccess": true,145 "noPropertyAccessFromIndexSignature": true146 }147}148```149150## Common Type Definitions151152### Fastify Extended Types153```typescript154import { FastifyRequest, FastifyInstance } from 'fastify';155156interface AuthUser {157 user_id: string;158 username: string;159 email: string;160 is_admin: boolean;161 scopes: string[];162}163164declare module 'fastify' {165 interface FastifyRequest {166 user: AuthUser;167 }168169 interface FastifyInstance {170 pg: {171 query: <T = unknown>(172 sql: string,173 params?: unknown[]174 ) => Promise<QueryResult<T>>;175 };176 authenticate: (177 request: FastifyRequest,178 reply: FastifyReply179 ) => Promise<void>;180 }181}182```183184### Error Types185```typescript186interface ErrorWithMessage {187 message: string;188}189190function isErrorWithMessage(error: unknown): error is ErrorWithMessage {191 return (192 typeof error === 'object' &&193 error !== null &&194 'message' in error &&195 typeof error.message === 'string'196 );197}198199function toErrorWithMessage(maybeError: unknown): ErrorWithMessage {200 if (isErrorWithMessage(maybeError)) return maybeError;201202 try {203 return new Error(JSON.stringify(maybeError));204 } catch {205 return new Error(String(maybeError));206 }207}208```209210## Workflow2112121. **Audit**: Search for `any` types: `grep -r "any" --include="*.ts"`2132. **Categorize**: Group by pattern (errors, requests, external libs, etc.)2143. **Define Types**: Create interfaces/types for each category2154. **Replace**: Systematically replace `any` with proper types2165. **Validate**: Ensure TypeScript compiles with `strict: true`2176. **Test**: Run all tests to ensure runtime behavior unchanged218219## Priority Order2202211. **Critical Path**: API routes, auth, database queries2222. **High Traffic**: Middleware, telemetry, error handlers2233. **Infrastructure**: Pulumi configs, build scripts2244. **Tests**: Test files (can be slightly more lenient but still typed)2255. **Scripts**: One-off scripts (still should be typed properly)226227## Success Metrics228229- **Zero** `any` types in production code230- **Zero** `@ts-ignore` comments231- **100%** TypeScript strict mode compliance232- **Green** CI/CD pipeline233- **No** runtime type errors from type mismatches234235---236237Remember: Type safety is not just about making TypeScript happy - it's about **preventing runtime bugs** and **making the codebase more maintainable**. Every `any` is a potential production bug waiting to happen.238
Also in pr-pm/prpm
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 |
|---|---|---|---|---|---|
| pr-pm/prpm.cursor/rules/karen-repo-reviewer.mdc · 121 | Cursor rules | archgit | 58/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/beanstalk-deploy.mdc · 121 | Cursor rules | teststyletypes | 62/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/core-principles.mdc · 121 | Cursor rules | testlint-formatstylearch+6 | 69/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/creating-agents-md.mdc · 121 | Cursor rules | testlint-formatstylearch+7 | 92/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/creating-cursor-rules.mdc · 121 | Cursor rules | testlint-formatstylearch+5 | 76/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/creating-kiro-agents.mdc · 121 | Cursor rules | setupbuildteststyle+5 | 76/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/creating-skills.mdc · 121 | Cursor rules | stylearchtesting-strategydo-not+1 | 61/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/format-conversion.mdc · 121 | Cursor rules | testlint-formatstyledo-not+1 | 63/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/github-actions-testing.mdc · 121 | Cursor rules | setupbuildstylearch+4 | 93/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/prpm-json-best-practices.mdc · 121 | Cursor rules | setuplint-formatstylearch+5 | 73/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/self-improve-cursor.mdc · 121 | Cursor rules | setuptestarchdependencies+3 | 69/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/testing-patterns.mdc · 121 | Cursor rules | testlint-formatstyletesting-strategy | 77/100 | 3 days ago | |
| pr-pm/prpm.cursor/rules/typescript-type-safety.mdc · 121 | Cursor rules | buildstylearchtypes+2 | 89/100 | 3 days ago | |
| pr-pm/prpmAGENTS.md · 121 | AGENTS.md | setupbuildtestlint-format+12 | 84/100 | 3 days ago | |
| pr-pm/prpmCLAUDE.md · 121 | CLAUDE.md | teststylegitapi+2 | 69/100 | 3 days ago |
Diff against .cursor/rules/karen-repo-reviewer.mdc Diff against .cursor/rules/beanstalk-deploy.mdc Diff against .cursor/rules/core-principles.mdc Diff against .cursor/rules/creating-agents-md.mdc Diff against .cursor/rules/creating-cursor-rules.mdc Diff against .cursor/rules/creating-kiro-agents.mdc Diff against .cursor/rules/creating-skills.mdc Diff against .cursor/rules/format-conversion.mdc Diff against .cursor/rules/github-actions-testing.mdc Diff against .cursor/rules/prpm-json-best-practices.mdc Diff against .cursor/rules/self-improve-cursor.mdc Diff against .cursor/rules/testing-patterns.mdc Diff against .cursor/rules/typescript-type-safety.mdc Diff against AGENTS.md Diff against CLAUDE.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 3 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 3 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 3 days ago |
