Files
upstream-atomic-crm/.claude/rules/typescript.md
upstream-mirror 93ecc1a6f8
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
snapshot of https://github.com/marmelab/atomic-crm.git (main, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:48:50 +05:00

2.3 KiB

paths
paths
**/*.ts
**/*.tsx
**/*.js
**/*.jsx

TypeScript / JavaScript

Types and interfaces

Use interface for object shapes that may be extended or implemented. Use type for unions, intersections, tuples, and utility types. Prefer string literal unions over enum unless interoperability requires it.

interface User {
  id: string
  email: string
}

type UserRole = 'admin' | 'member'
type UserWithRole = User & { role: UserRole }

Add explicit parameter and return types to exported functions and public class methods. Let TypeScript infer obvious local variable types.

Avoid any

Never use any in application code. Use unknown for external or untrusted input, then narrow safely. Use generics when a value's type depends on the caller.

// Wrong
function getErrorMessage(error: any) {
  return error.message
}

// Correct
function getErrorMessage(error: unknown): string {
  if (error instanceof Error) return error.message
  return 'Unexpected error'
}

React props

Define component props with a named interface or type. Type callback props explicitly. Do not use React.FC unless there is a specific reason.

interface UserCardProps {
  user: User
  onSelect: (id: string) => void
}

function UserCard({ user, onSelect }: UserCardProps) {
  return <button onClick={() => onSelect(user.id)}>{user.email}</button>
}

Input validation with Zod

Use Zod for schema-based validation and infer types from the schema. Do not duplicate type definitions — infer from the schema.

import { z } from 'zod'

const userSchema = z.object({
  email: z.string().email(),
  age: z.number().int().min(0).max(150)
})

type UserInput = z.infer<typeof userSchema>
const validated: UserInput = userSchema.parse(input)

Error handling

Use async/await with try-catch. Always narrow unknown errors before accessing properties.

async function loadUser(userId: string): Promise<User> {
  try {
    return await riskyOperation(userId)
  } catch (error: unknown) {
    logger.error('Operation failed', error)
    throw new Error(getErrorMessage(error))
  }
}

console.log

No console.log in production code. Use a proper logging library.