typescript-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TypeScript Best Practices

TypeScript最佳实践

Guide AI agents in writing high-quality TypeScript code. This skill provides coding standards, architecture patterns, and tools for analysis and scaffolding.
指导AI Agent编写高质量的TypeScript代码。本技能提供编码标准、架构模式以及用于分析和脚手架的工具。

When to Use This Skill

何时使用此技能

Use this skill when:
  • Generating new TypeScript code
  • Reviewing TypeScript files for quality issues
  • Creating new modules, services, or components
  • Refactoring JavaScript to TypeScript
  • Answering questions about TypeScript patterns or types
  • Designing APIs or interfaces
Do NOT use this skill when:
  • Working with pure JavaScript (no TypeScript)
  • Debugging runtime errors (use debugging tools)
  • Framework-specific patterns (React, Vue, etc. - use framework skills)
在以下场景使用此技能:
  • 生成新的TypeScript代码
  • 审查TypeScript文件以发现质量问题
  • 创建新的模块、服务或组件
  • 将JavaScript重构为TypeScript
  • 解答关于TypeScript模式或类型的问题
  • 设计API或接口
请勿在以下场景使用:
  • 处理纯JavaScript代码(无TypeScript)
  • 调试运行时错误(使用调试工具)
  • 框架特定模式(React、Vue等 - 使用对应框架技能)

Core Principles

核心原则

1. Type Safety First

1. 优先保证类型安全

Maximize compile-time error detection:
typescript
// Prefer unknown over any for unknown types
function processInput(data: unknown): string {
  if (typeof data === "string") return data;
  if (typeof data === "number") return String(data);
  throw new Error("Unsupported type");
}

// Explicit return types for public APIs
export function calculateTotal(items: ReadonlyArray<Item>): number {
  return items.reduce((sum, item) => sum + item.price, 0);
}

// Use const assertions for literal types
const CONFIG = {
  mode: "production",
  version: 1,
} as const;
最大化编译时错误检测:
typescript
// 对于未知类型,优先使用unknown而非any
function processInput(data: unknown): string {
  if (typeof data === "string") return data;
  if (typeof data === "number") return String(data);
  throw new Error("Unsupported type");
}

// 公共API使用显式返回类型
export function calculateTotal(items: ReadonlyArray<Item>): number {
  return items.reduce((sum, item) => sum + item.price, 0);
}

// 对字面量类型使用const断言
const CONFIG = {
  mode: "production",
  version: 1,
} as const;

2. Immutability by Default

2. 默认使用不可变性

Prevent accidental mutations:
typescript
// Use readonly for object properties
interface User {
  readonly id: string;
  readonly email: string;
  name: string; // Only mutable if intentional
}

// Use ReadonlyArray for collections
function processItems(items: ReadonlyArray<Item>): ReadonlyArray<Result> {
  return items.map(transform);
}

// Prefer spreading over mutation
function updateUser(user: User, name: string): User {
  return { ...user, name };
}
防止意外修改:
typescript
// 对对象属性使用readonly
interface User {
  readonly id: string;
  readonly email: string;
  name: string; // 仅在有意时设为可变
}

// 对集合使用ReadonlyArray
function processItems(items: ReadonlyArray<Item>): ReadonlyArray<Result> {
  return items.map(transform);
}

// 优先使用扩展语法而非直接修改
function updateUser(user: User, name: string): User {
  return { ...user, name };
}

3. Error Handling with Types

3. 结合类型系统处理错误

Use the type system for error handling:
typescript
// Result type for recoverable errors
type Result<T, E = Error> =
  | { success: true; value: T }
  | { success: false; error: E };

// Typed error classes
class ValidationError extends Error {
  constructor(
    message: string,
    readonly field: string,
    readonly code: string
  ) {
    super(message);
    this.name = "ValidationError";
  }
}

// Function with Result return type
function parseConfig(input: string): Result<Config, ValidationError> {
  try {
    const data = JSON.parse(input);
    if (!isValidConfig(data)) {
      return {
        success: false,
        error: new ValidationError("Invalid config", "root", "INVALID_FORMAT"),
      };
    }
    return { success: true, value: data };
  } catch {
    return {
      success: false,
      error: new ValidationError("Parse failed", "root", "PARSE_ERROR"),
    };
  }
}
利用类型系统进行错误处理:
typescript
// 用于可恢复错误的Result类型
type Result<T, E = Error> =
  | { success: true; value: T }
  | { success: false; error: E };

// 带类型的错误类
class ValidationError extends Error {
  constructor(
    message: string,
    readonly field: string,
    readonly code: string
  ) {
    super(message);
    this.name = "ValidationError";
  }
}

// 返回Result类型的函数
function parseConfig(input: string): Result<Config, ValidationError> {
  try {
    const data = JSON.parse(input);
    if (!isValidConfig(data)) {
      return {
        success: false,
        error: new ValidationError("Invalid config", "root", "INVALID_FORMAT"),
      };
    }
    return { success: true, value: data };
  } catch {
    return {
      success: false,
      error: new ValidationError("Parse failed", "root", "PARSE_ERROR"),
    };
  }
}

4. Code Organization

4. 代码组织

Structure code for maintainability:
typescript
// One concept per file
// user.ts - User type and related utilities
export interface User {
  readonly id: string;
  readonly email: string;
  readonly createdAt: Date;
}

export function createUser(email: string): User {
  return {
    id: crypto.randomUUID(),
    email,
    createdAt: new Date(),
  };
}

// Explicit exports (no barrel file wildcards)
// index.ts
export { User, createUser } from "./user.ts";
export { validateEmail } from "./validation.ts";
结构化代码以提升可维护性:
typescript
// 每个文件对应一个概念
// user.ts - User类型及相关工具函数
export interface User {
  readonly id: string;
  readonly email: string;
  readonly createdAt: Date;
}

export function createUser(email: string): User {
  return {
    id: crypto.randomUUID(),
    email,
    createdAt: new Date(),
  };
}

// 显式导出(避免桶文件通配符)
// index.ts
export { User, createUser } from "./user.ts";
export { validateEmail } from "./validation.ts";

Quick Reference

快速参考

CategoryPreferAvoid
Unknown types
unknown
any
Collections
ReadonlyArray<T>
T[]
for inputs
Objects
Readonly<T>
Mutable by default
Null checksOptional chaining
?.
!= null
Type narrowingType guards
as
assertions
Return typesExplicit on exportsInferred on exports
EnumsString literal unionsNumeric enums
ImportsNamed importsDefault imports
ErrorsResult typesThrowing for flow control
Loops
for...of
,
.map()
for...in
on arrays
分类推荐避免
未知类型
unknown
any
集合
ReadonlyArray<T>
输入使用
T[]
对象
Readonly<T>
默认设为可变
空值检查可选链
?.
!= null
类型收窄类型守卫
as
断言
返回类型导出函数使用显式类型导出函数使用推断类型
枚举字符串字面量联合数字枚举
导入具名导入默认导入
错误处理Result类型为流程控制抛出错误
循环
for...of
,
.map()
在数组上使用
for...in

Code Generation Guidelines

代码生成指南

When generating TypeScript code, follow these patterns:
生成TypeScript代码时,请遵循以下模式:

Module Structure

模块结构

typescript
/**
 * Module description
 * @module module-name
 */

// === Types ===
export interface ModuleOptions {
  readonly setting: string;
}

export interface ModuleResult {
  readonly data: unknown;
}

// === Constants ===
const DEFAULT_OPTIONS: ModuleOptions = {
  setting: "default",
};

// === Implementation ===
export function processData(
  input: unknown,
  options: Partial<ModuleOptions> = {}
): ModuleResult {
  const opts = { ...DEFAULT_OPTIONS, ...options };
  // Implementation
  return { data: input };
}
typescript
/**
 * 模块描述
 * @module module-name
 */

// === 类型定义 ===
export interface ModuleOptions {
  readonly setting: string;
}

export interface ModuleResult {
  readonly data: unknown;
}

// === 常量定义 ===
const DEFAULT_OPTIONS: ModuleOptions = {
  setting: "default",
};

// === 实现逻辑 ===
export function processData(
  input: unknown,
  options: Partial<ModuleOptions> = {}
): ModuleResult {
  const opts = { ...DEFAULT_OPTIONS, ...options };
  // 实现代码
  return { data: input };
}

Function Design

函数设计

typescript
// Pure functions preferred
function transform(input: Input): Output {
  // No side effects, same input = same output
  return { ...input, processed: true };
}

// Explicit parameter types
function fetchUser(id: string, options?: FetchOptions): Promise<User> {
  // Implementation
}

// Use function overloads for complex signatures
function parse(input: string): ParsedData;
function parse(input: Buffer): ParsedData;
function parse(input: string | Buffer): ParsedData {
  // Implementation
}
typescript
// 优先使用纯函数
function transform(input: Input): Output {
  // 无副作用,相同输入得到相同输出
  return { ...input, processed: true };
}

// 显式参数类型
function fetchUser(id: string, options?: FetchOptions): Promise<User> {
  // 实现代码
}

// 复杂签名使用函数重载
function parse(input: string): ParsedData;
function parse(input: Buffer): ParsedData;
function parse(input: string | Buffer): ParsedData {
  // 实现代码
}

Interface Design

接口设计

typescript
// Prefer interfaces for object shapes
interface UserData {
  readonly id: string;
  readonly email: string;
}

// Use type for unions and intersections
type UserRole = "admin" | "user" | "guest";
type AdminUser = UserData & { readonly role: "admin" };

// Document with JSDoc
/**
 * Configuration for the API client
 * @property baseUrl - The base URL for API requests
 * @property timeout - Request timeout in milliseconds
 */
interface ApiConfig {
  readonly baseUrl: string;
  readonly timeout?: number;
}
typescript
// 对象形状优先使用interface
interface UserData {
  readonly id: string;
  readonly email: string;
}

// 联合类型和交叉类型使用type
type UserRole = "admin" | "user" | "guest";
type AdminUser = UserData & { readonly role: "admin" };

// 使用JSDoc添加文档
/**
 * API客户端配置
 * @property baseUrl - API请求的基础URL
 * @property timeout - 请求超时时间(毫秒)
 */
interface ApiConfig {
  readonly baseUrl: string;
  readonly timeout?: number;
}

Common Anti-Patterns

常见反模式

Avoid these patterns when generating code:
Anti-PatternProblemSolution
any
type
Disables type checkingUse
unknown
and narrow
as
assertions
Runtime errorsUse type guards
Non-null
!
Null pointer errorsOptional chaining
?.
Mutable paramsUnexpected mutations
Readonly<T>
Magic stringsTypos, no autocompleteString literal types
God classesHard to test/maintainSingle responsibility
Circular depsBuild/runtime issuesDependency inversion
Index signaturesLose type infoExplicit properties
See
references/anti-patterns/common-mistakes.md
for detailed examples.
生成代码时请避免以下模式:
反模式问题解决方案
any
类型
禁用类型检查使用
unknown
并进行类型收窄
as
断言
可能导致运行时错误使用类型守卫
非空断言
!
空指针错误风险使用可选链
?.
可变参数意外修改风险使用
Readonly<T>
魔法字符串拼写错误、无自动补全使用字符串字面量联合
上帝类难以测试和维护单一职责原则
循环依赖构建/运行时问题依赖反转原则
索引签名丢失类型信息使用显式属性
详细示例请参阅
references/anti-patterns/common-mistakes.md

Scripts Reference

脚本参考

analyze.ts

analyze.ts

Analyze TypeScript code for quality issues:
bash
deno run --allow-read scripts/analyze.ts <path> [options]

Options:
  --strict        Enable all checks
  --json          Output JSON for programmatic use
  --fix-hints     Show suggested fixes

Examples:
  # Analyze a file
  deno run --allow-read scripts/analyze.ts ./src/utils.ts

  # Analyze directory with strict mode
  deno run --allow-read scripts/analyze.ts ./src --strict

  # JSON output for CI
  deno run --allow-read scripts/analyze.ts ./src --json
分析TypeScript代码以发现质量问题:
bash
deno run --allow-read scripts/analyze.ts <path> [options]

选项:
  --strict        启用所有检查
  --json          输出JSON格式以支持程序化使用
  --fix-hints     显示建议的修复方案

示例:
  # 分析单个文件
  deno run --allow-read scripts/analyze.ts ./src/utils.ts

  # 以严格模式分析目录
  deno run --allow-read scripts/analyze.ts ./src --strict

  # 输出JSON格式用于CI
  deno run --allow-read scripts/analyze.ts ./src --json

generate-types.ts

generate-types.ts

Generate TypeScript types from JSON data:
bash
deno run --allow-read --allow-write scripts/generate-types.ts <input> [options]

Options:
  --name <name>   Root type name (default: inferred)
  --output <path> Output file path
  --readonly      Generate readonly types
  --interface     Use interface instead of type

Examples:
  # Generate from JSON file
  deno run --allow-read scripts/generate-types.ts ./data.json --name Config

  # Generate readonly interface
  deno run --allow-read --allow-write scripts/generate-types.ts ./api-response.json \
    --interface --readonly --output ./types/api.ts
从JSON数据生成TypeScript类型:
bash
deno run --allow-read --allow-write scripts/generate-types.ts <input> [options]

选项:
  --name <name>   根类型名称(默认:自动推断)
  --output <path> 输出文件路径
  --readonly      生成只读类型
  --interface     使用interface而非type

示例:
  # 从JSON文件生成类型
  deno run --allow-read scripts/generate-types.ts ./data.json --name Config

  # 生成只读interface
  deno run --allow-read --allow-write scripts/generate-types.ts ./api-response.json \
    --interface --readonly --output ./types/api.ts

scaffold-module.ts

scaffold-module.ts

Create properly structured TypeScript modules:
bash
deno run --allow-read --allow-write scripts/scaffold-module.ts [options]

Options:
  --name <name>   Module name (required)
  --path <path>   Target directory (default: ./src)
  --type <type>   Type: service, util, component
  --with-tests    Include test file

Examples:
  # Create a utility module
  deno run --allow-read --allow-write scripts/scaffold-module.ts \
    --name "string-utils" --type util

  # Create a service with tests
  deno run --allow-read --allow-write scripts/scaffold-module.ts \
    --name "user-service" --type service --with-tests
创建结构规范的TypeScript模块:
bash
deno run --allow-read --allow-write scripts/scaffold-module.ts [options]

选项:
  --name <name>   模块名称(必填)
  --path <path>   目标目录(默认:./src)
  --type <type>   类型:service, util, component
  --with-tests    包含测试文件

示例:
  # 创建工具模块
  deno run --allow-read --allow-write scripts/scaffold-module.ts \
    --name "string-utils" --type util

  # 创建带测试的服务模块
  deno run --allow-read --allow-write scripts/scaffold-module.ts \
    --name "user-service" --type service --with-tests

Additional Resources

额外资源

Type System Deep Dives

类型系统深入解析

  • references/type-system/advanced-types.md
    - Generics, conditional types, mapped types
  • references/type-system/type-guards.md
    - Type narrowing techniques
  • references/type-system/utility-types.md
    - Built-in utility types
  • references/type-system/advanced-types.md
    - 泛型、条件类型、映射类型
  • references/type-system/type-guards.md
    - 类型收窄技巧
  • references/type-system/utility-types.md
    - 内置工具类型

Pattern Guides

模式指南

  • references/patterns/error-handling.md
    - Result types, typed errors
  • references/patterns/async-patterns.md
    - Async/await best practices
  • references/patterns/functional-patterns.md
    - Immutability, composition
  • references/patterns/module-patterns.md
    - Exports, dependency injection
  • references/patterns/error-handling.md
    - Result类型、带类型的错误
  • references/patterns/async-patterns.md
    - Async/await最佳实践
  • references/patterns/functional-patterns.md
    - 不可变性、组合式编程
  • references/patterns/module-patterns.md
    - 导出规范、依赖注入

Architecture

架构

  • references/architecture/project-structure.md
    - Directory organization
  • references/architecture/api-design.md
    - Interface design, versioning
  • references/architecture/project-structure.md
    - 目录组织
  • references/architecture/api-design.md
    - 接口设计、版本控制

Templates

模板

  • assets/templates/module-template.ts.md
    - Module starter template
  • assets/templates/service-template.ts.md
    - Service class template
  • assets/tsconfig-presets/strict.json
    - Maximum strictness config
  • assets/tsconfig-presets/recommended.json
    - Balanced defaults
  • assets/templates/module-template.ts.md
    - 模块启动模板
  • assets/templates/service-template.ts.md
    - 服务类模板
  • assets/tsconfig-presets/strict.json
    - 最高严格度配置
  • assets/tsconfig-presets/recommended.json
    - 平衡的默认配置