typescript-rules

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TypeScript Development Rules (Frontend)

TypeScript前端开发规范

Basic Principles

基本原则

Aggressive Refactoring - Prevent technical debt and maintain health ❌ Unused "Just in Case" Code - Violates YAGNI principle (Kent Beck)
积极重构 - 预防技术债务,保持代码健康 ❌ 冗余的「以防万一」代码 - 违反YAGNI原则(Kent Beck提出)

Comment Writing Rules

注释编写规则

  • Function Description Focus: Describe what the code "does"
  • No Historical Information: Do not record development history
  • Timeless: Write only content that remains valid whenever read
  • Conciseness: Keep explanations to necessary minimum
  • 聚焦函数描述:说明代码「做什么」
  • 不记录历史信息:不要留存开发历史记录
  • 时效性无关:仅编写任何时间阅读都有效的内容
  • 简洁性:仅保留必要的解释内容

Type Safety

类型安全

Absolute Rule: any type is completely prohibited. It disables type checking and becomes a source of runtime errors.
any Type Alternatives (Priority Order)
  1. unknown Type + Type Guards: Use for validating external input (API responses, localStorage, URL parameters)
  2. Generics: When type flexibility is needed
  3. Union Types・Intersection Types: Combinations of multiple types
  4. Type Assertions (Last Resort): Only when type is certain
Type Guard Implementation Pattern
typescript
function isUser(value: unknown): value is User {
  return typeof value === 'object' && value !== null && 'id' in value && 'name' in value
}
Modern Type Features
  • satisfies Operator:
    const config = { apiUrl: '/api' } satisfies Config
    - Preserves inference
  • const Assertion:
    const ROUTES = { HOME: '/' } as const satisfies Routes
    - Immutable and type-safe
  • Branded Types:
    type UserId = string & { __brand: 'UserId' }
    - Distinguish meaning
  • Template Literal Types:
    type EventName = \
    on${Capitalize<string>}`` - Express string patterns with types
Type Safety in Frontend Implementation
  • React Props/State: TypeScript manages types, unknown unnecessary
  • External API Responses: Always receive as
    unknown
    , validate with type guards
  • localStorage/sessionStorage: Treat as
    unknown
    , validate
  • URL Parameters: Treat as
    unknown
    , validate
  • Form Input (Controlled Components): Type-safe with React synthetic events
Type Safety in Data Flow
  • Frontend → Backend: Props/State (Type Guaranteed) → API Request (Serialization)
  • Backend → Frontend: API Response (
    unknown
    ) → Type Guard → State (Type Guaranteed)
Type Complexity Management
  • Props Design:
    • Props count: 3-7 props ideal (consider component splitting if exceeds 10)
    • Optional Props: 50% or less (consider default values or Context if excessive)
    • Nesting: Up to 2 levels (flatten deeper structures)
  • Type Assertions: Review design if used 3+ times
  • External API Types: Relax constraints and define according to reality (convert appropriately internally)
绝对规则:完全禁止使用any类型。它会禁用类型检查,成为运行时错误的源头。
any类型替代方案(优先级排序)
  1. unknown类型 + 类型守卫:用于验证外部输入(API响应、localStorage、URL参数)
  2. 泛型:需要类型灵活性时使用
  3. 联合类型・交叉类型:多种类型的组合
  4. 类型断言(最后手段):仅在确定类型时使用
类型守卫实现模式
typescript
function isUser(value: unknown): value is User {
  return typeof value === 'object' && value !== null && 'id' in value && 'name' in value
}
现代类型特性
  • satisfies操作符
    const config = { apiUrl: '/api' } satisfies Config
    - 保留类型推断
  • const断言
    const ROUTES = { HOME: '/' } as const satisfies Routes
    - 不可变且类型安全
  • 品牌类型
    type UserId = string & { __brand: 'UserId' }
    - 区分类型含义
  • 模板字面量类型
    type EventName = \
    on${Capitalize<string>}`` - 用类型表达字符串模式
前端实现中的类型安全
  • React Props/State:由TypeScript管理类型,无需使用unknown
  • 外部API响应:始终以unknown类型接收,通过类型守卫验证
  • localStorage/sessionStorage:视为unknown类型,进行验证
  • URL参数:视为unknown类型,进行验证
  • 表单输入(受控组件):通过React合成事件实现类型安全
数据流中的类型安全
  • 前端 → 后端:Props/State(类型已保障)→ API请求(序列化)
  • 后端 → 前端:API响应(unknown)→ 类型守卫 → State(类型已保障)
类型复杂度管理
  • Props设计
    • Props数量:理想为3-7个(超过10个时考虑拆分组件)
    • 可选Props:占比不超过50%(过多时考虑默认值或Context)
    • 嵌套层级:最多2层(深层结构需扁平化)
  • 类型断言:若使用超过3次,需重新审视设计
  • 外部API类型:根据实际情况放宽约束并定义(内部按需转换)

Coding Conventions

编码规范

Component Design Criteria
  • Function Components (Mandatory): Official React recommendation, optimizable by modern tooling
  • Classes Prohibited: Class components completely deprecated (Exception: Error Boundary)
  • Custom Hooks: Standard pattern for logic reuse and dependency injection
  • Component Hierarchy: Atoms → Molecules → Organisms → Templates → Pages
  • Co-location: Place tests, styles, and related files alongside components
State Management Patterns
  • Local State:
    useState
    for component-specific state
  • Context API: For sharing state across component tree (theme, auth, etc.)
  • Custom Hooks: Encapsulate state logic and side effects
  • Server State: React Query or SWR for API data caching
Data Flow Principles
  • Single Source of Truth: Each piece of state has one authoritative source
  • Unidirectional Flow: Data flows top-down via props
  • Immutable Updates: Use immutable patterns for state updates
typescript
// ✅ Immutable state update
setUsers(prev => [...prev, newUser])

// ❌ Mutable state update
users.push(newUser)
setUsers(users)
Function Design
  • 0-2 parameters maximum: Use object for 3+ parameters
    typescript
    // ✅ Object parameter
    function createUser({ name, email, role }: CreateUserParams) {}
Props Design (Props-driven Approach)
  • Props are the interface: Define all necessary information as props
  • Avoid implicit dependencies: Do not depend on global state or context without necessity
  • Type-safe: Always define Props type explicitly
Environment Variables
  • Use build tool's environment variable system:
    process.env
    does not work in browsers
  • Centrally manage environment variables through configuration layer
  • Implement proper type safety and default value handling
typescript
// ✅ Build tool environment variables (public values only)
const config = {
  apiUrl: import.meta.env.API_URL || 'http://localhost:3000',
  appName: import.meta.env.APP_NAME || 'My App'
}

// ❌ Does not work in frontend
const apiUrl = process.env.API_URL
Security (Client-side Constraints)
  • CRITICAL: All frontend code is public and visible in browser
  • Never store secrets client-side: No API keys, tokens, or secrets in environment variables
  • Do not include
    .env
    files in Git
  • Do not include sensitive information in error messages
typescript
// ❌ Security risk: API key exposed in browser
const apiKey = import.meta.env.API_KEY
const response = await fetch(`https://api.example.com/data?key=${apiKey}`)

// ✅ Correct: Backend manages secrets, frontend accesses via proxy
const response = await fetch('/api/data') // Backend handles API key authentication
Dependency Injection
  • Custom Hooks for dependency injection: Ensure testability and modularity
Asynchronous Processing
  • Promise Handling: Always use
    async/await
  • Error Handling: Always handle with
    try-catch
    or Error Boundary
  • Type Definition: Explicitly define return value types (e.g.,
    Promise<Result>
    )
Format Rules
  • Semicolon omission (follow Biome settings)
  • Types in
    PascalCase
    , variables/functions in
    camelCase
  • Imports use absolute paths (
    src/
    )
Clean Code Principles
  • ✅ Delete unused code immediately
  • ✅ Delete debug
    console.log()
  • ❌ Commented-out code (manage history with version control)
  • ✅ Comments explain "why" (not "what")
组件设计准则
  • 必须使用函数式组件:React官方推荐,可通过现代工具优化
  • 禁止使用类组件:类组件已完全弃用(例外:错误边界Error Boundary)
  • 自定义Hooks:逻辑复用与依赖注入的标准模式
  • 组件层级:原子组件 → 分子组件 → 组织组件 → 模板 → 页面
  • 就近原则:将测试、样式及相关文件与组件放在同一目录
状态管理模式
  • 局部状态:使用useState管理组件专属状态
  • Context API:用于在组件树间共享状态(主题、权限等)
  • 自定义Hooks:封装状态逻辑与副作用
  • 服务端状态:使用React Query或SWR处理API数据缓存
数据流原则
  • 单一数据源:每个状态仅存在一个权威来源
  • 单向数据流:数据通过props自上而下传递
  • 不可变更新:使用不可变模式更新状态
typescript
// ✅ 不可变状态更新
setUsers(prev => [...prev, newUser])

// ❌ 可变状态更新
users.push(newUser)
setUsers(users)
函数设计
  • 最多0-2个参数:参数超过3个时使用对象传递
    typescript
    // ✅ 对象参数
    function createUser({ name, email, role }: CreateUserParams) {}
Props设计(Props驱动)
  • Props即接口:将所有必要信息定义为Props
  • 避免隐式依赖:非必要时不要依赖全局状态或Context
  • 类型安全:始终显式定义Props类型
环境变量
  • 使用构建工具的环境变量系统:process.env在浏览器中无法生效
  • 通过配置层集中管理环境变量
  • 实现适当的类型安全与默认值处理
typescript
// ✅ 构建工具环境变量(仅公开值)
const config = {
  apiUrl: import.meta.env.API_URL || 'http://localhost:3000',
  appName: import.meta.env.APP_NAME || 'My App'
}

// ❌ 前端环境下无法生效
const apiUrl = process.env.API_URL
安全(客户端约束)
  • 关键注意:所有前端代码都是公开的,可在浏览器中查看
  • 绝不在客户端存储敏感信息:环境变量中不要包含API密钥、令牌或机密信息
  • 不要将.env文件纳入Git版本控制
  • 错误信息中不要包含敏感信息
typescript
// ❌ 安全风险:API密钥在浏览器中暴露
const apiKey = import.meta.env.API_KEY
const response = await fetch(`https://api.example.com/data?key=${apiKey}`)

// ✅ 正确做法:后端管理敏感信息,前端通过代理访问
const response = await fetch('/api/data') // 后端处理API密钥认证
依赖注入
  • 使用自定义Hooks实现依赖注入:确保可测试性与模块化
异步处理
  • Promise处理:始终使用async/await
  • 错误处理:始终通过try-catch或Error Boundary处理
  • 类型定义:显式定义返回值类型(例如:
    Promise<Result>
格式规则
  • 省略分号(遵循Biome配置)
  • 类型使用PascalCase命名,变量/函数使用camelCase命名
  • 导入使用绝对路径(
    src/
    开头)
整洁代码原则
  • ✅ 立即删除未使用的代码
  • ✅ 删除调试用的
    console.log()
  • ❌ 不要保留注释掉的代码(通过版本控制管理历史)
  • ✅ 注释说明「为什么」(而非「做什么」)

Error Handling

错误处理

Absolute Rule: Error suppression prohibited. All errors must have log output and appropriate handling.
Fail-Fast Principle: Fail quickly on errors to prevent continued processing in invalid states
typescript
// ❌ Prohibited: Unconditional fallback
catch (error) {
  return defaultValue // Hides error
}

// ✅ Required: Explicit failure
catch (error) {
  logger.error('Processing failed', error)
  throw error // Handle with Error Boundary or higher layer
}
Result Type Pattern: Express errors with types for explicit handling
typescript
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }

// Example: Express error possibility with types
function parseUser(data: unknown): Result<User, ValidationError> {
  if (!isValid(data)) return { ok: false, error: new ValidationError() }
  return { ok: true, value: data as User }
}
Custom Error Classes
typescript
export class AppError extends Error {
  constructor(message: string, public readonly code: string, public readonly statusCode = 500) {
    super(message)
    this.name = this.constructor.name
  }
}
// Purpose-specific: ValidationError(400), ApiError(502), NotFoundError(404)
Layer-Specific Error Handling (React)
  • Error Boundary: Catch React component errors, display fallback UI
  • Custom Hook: Detect business rule violations, propagate AppError as-is
  • API Layer: Convert fetch errors to domain errors
Structured Logging and Sensitive Information Protection Never include sensitive information (password, token, apiKey, secret, creditCard) in logs
Asynchronous Error Handling in React
  • Error Boundary setup mandatory: Catch rendering errors
  • Use try-catch with all async/await in event handlers
  • Always log and re-throw errors or display error state
绝对规则:禁止抑制错误。所有错误必须记录日志并进行适当处理。
快速失败原则:遇到错误时立即终止,防止在无效状态下继续处理
typescript
// ❌ 禁止:无条件回退
catch (error) {
  return defaultValue // 隐藏错误
}

// ✅ 必须:显式处理失败
catch (error) {
  logger.error('处理失败', error)
  throw error // 由Error Boundary或上层处理
}
Result类型模式:通过类型表达错误,实现显式处理
typescript
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }

// 示例:用类型表达错误可能性
function parseUser(data: unknown): Result<User, ValidationError> {
  if (!isValid(data)) return { ok: false, error: new ValidationError() }
  return { ok: true, value: data as User }
}
自定义错误类
typescript
export class AppError extends Error {
  constructor(message: string, public readonly code: string, public readonly statusCode = 500) {
    super(message)
    this.name = this.constructor.name
  }
}
// 按用途细分:ValidationError(400), ApiError(502), NotFoundError(404)
React分层错误处理
  • Error Boundary:捕获React组件错误,显示回退UI
  • 自定义Hooks:检测业务规则违规,直接传播AppError
  • API层:将fetch错误转换为领域错误
结构化日志与敏感信息保护 日志中绝不能包含敏感信息(密码、令牌、apiKey、机密、信用卡信息)
React异步错误处理
  • 必须设置Error Boundary:捕获渲染错误
  • 事件处理中的所有async/await都要使用try-catch
  • 始终记录日志并重新抛出错误,或显示错误状态

Refactoring Techniques

重构技巧

Basic Policy
  • Small Steps: Maintain always-working state through gradual improvements
  • Safe Changes: Minimize the scope of changes at once
  • Behavior Guarantee: Ensure existing behavior remains unchanged while proceeding
Implementation Procedure: Understand Current State → Gradual Changes → Behavior Verification → Final Validation
Priority: Duplicate Code Removal > Large Function Division > Complex Conditional Branch Simplification > Type Safety Improvement
基本策略
  • 小步迭代:通过渐进式改进始终保持代码可运行
  • 安全变更:每次最小化变更范围
  • 行为保障:在重构过程中确保现有行为不变
实施流程:理解当前状态 → 渐进式变更 → 行为验证 → 最终确认
优先级:移除重复代码 > 拆分大函数 > 简化复杂条件分支 > 提升类型安全

Performance Optimization

性能优化

  • Component Memoization: Use React.memo for expensive components
  • State Optimization: Minimize re-renders with proper state structure
  • Lazy Loading: Use React.lazy and Suspense for code splitting
  • Bundle Size: Monitor with the
    build
    script and keep under 500KB
  • 组件记忆化:对性能开销大的组件使用React.memo
  • 状态优化:通过合理的状态结构减少重渲染
  • 懒加载:使用React.lazy和Suspense实现代码拆分
  • 包体积:通过
    build
    脚本监控,保持在500KB以内

Non-functional Requirements

非功能性需求

  • Browser Compatibility: Chrome/Firefox/Safari/Edge (latest 2 versions)
  • Rendering Time: Within 5 seconds for major pages
  • 浏览器兼容性:Chrome/Firefox/Safari/Edge(最新2个版本)
  • 渲染时间:主要页面加载时间控制在5秒以内