typescript-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTypeScript 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
快速参考
| Category | Prefer | Avoid |
|---|---|---|
| Unknown types | | |
| Collections | | |
| Objects | | Mutable by default |
| Null checks | Optional chaining | |
| Type narrowing | Type guards | |
| Return types | Explicit on exports | Inferred on exports |
| Enums | String literal unions | Numeric enums |
| Imports | Named imports | Default imports |
| Errors | Result types | Throwing for flow control |
| Loops | | |
| 分类 | 推荐 | 避免 |
|---|---|---|
| 未知类型 | | |
| 集合 | | 输入使用 |
| 对象 | | 默认设为可变 |
| 空值检查 | 可选链 | |
| 类型收窄 | 类型守卫 | |
| 返回类型 | 导出函数使用显式类型 | 导出函数使用推断类型 |
| 枚举 | 字符串字面量联合 | 数字枚举 |
| 导入 | 具名导入 | 默认导入 |
| 错误处理 | Result类型 | 为流程控制抛出错误 |
| 循环 | | 在数组上使用 |
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-Pattern | Problem | Solution |
|---|---|---|
| Disables type checking | Use |
| Runtime errors | Use type guards |
Non-null | Null pointer errors | Optional chaining |
| Mutable params | Unexpected mutations | |
| Magic strings | Typos, no autocomplete | String literal types |
| God classes | Hard to test/maintain | Single responsibility |
| Circular deps | Build/runtime issues | Dependency inversion |
| Index signatures | Lose type info | Explicit properties |
See for detailed examples.
references/anti-patterns/common-mistakes.md生成代码时请避免以下模式:
| 反模式 | 问题 | 解决方案 |
|---|---|---|
| 禁用类型检查 | 使用 |
| 可能导致运行时错误 | 使用类型守卫 |
非空断言 | 空指针错误风险 | 使用可选链 |
| 可变参数 | 意外修改风险 | 使用 |
| 魔法字符串 | 拼写错误、无自动补全 | 使用字符串字面量联合 |
| 上帝类 | 难以测试和维护 | 单一职责原则 |
| 循环依赖 | 构建/运行时问题 | 依赖反转原则 |
| 索引签名 | 丢失类型信息 | 使用显式属性 |
详细示例请参阅。
references/anti-patterns/common-mistakes.mdScripts 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 --jsongenerate-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.tsscaffold-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-testsAdditional Resources
额外资源
Type System Deep Dives
类型系统深入解析
- - Generics, conditional types, mapped types
references/type-system/advanced-types.md - - Type narrowing techniques
references/type-system/type-guards.md - - Built-in utility types
references/type-system/utility-types.md
- - 泛型、条件类型、映射类型
references/type-system/advanced-types.md - - 类型收窄技巧
references/type-system/type-guards.md - - 内置工具类型
references/type-system/utility-types.md
Pattern Guides
模式指南
- - Result types, typed errors
references/patterns/error-handling.md - - Async/await best practices
references/patterns/async-patterns.md - - Immutability, composition
references/patterns/functional-patterns.md - - Exports, dependency injection
references/patterns/module-patterns.md
- - Result类型、带类型的错误
references/patterns/error-handling.md - - Async/await最佳实践
references/patterns/async-patterns.md - - 不可变性、组合式编程
references/patterns/functional-patterns.md - - 导出规范、依赖注入
references/patterns/module-patterns.md
Architecture
架构
- - Directory organization
references/architecture/project-structure.md - - Interface design, versioning
references/architecture/api-design.md
- - 目录组织
references/architecture/project-structure.md - - 接口设计、版本控制
references/architecture/api-design.md
Templates
模板
- - Module starter template
assets/templates/module-template.ts.md - - Service class template
assets/templates/service-template.ts.md - - Maximum strictness config
assets/tsconfig-presets/strict.json - - Balanced defaults
assets/tsconfig-presets/recommended.json
- - 模块启动模板
assets/templates/module-template.ts.md - - 服务类模板
assets/templates/service-template.ts.md - - 最高严格度配置
assets/tsconfig-presets/strict.json - - 平衡的默认配置
assets/tsconfig-presets/recommended.json