typescript-excellence

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TypeScript Excellence

卓越TypeScript实践

Type-safe, maintainable TypeScript with modern toolchain.
打造类型安全、可维护的TypeScript代码与现代化工具链。

Type Safety

类型安全

Never use
any
. Alternatives:
typescript
// Unknown for external data
function parse(input: unknown): User { ... }

// Union for specific options
type Status = 'loading' | 'success' | 'error';

// Generics for reusable code
function first<T>(arr: T[]): T | undefined { ... }

// Type assertion as last resort (with runtime check)
if (isUser(data)) { return data as User; }
tsconfig.json essentials:
json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true
  }
}
绝不使用
any
类型
。替代方案:
typescript
// 外部数据使用Unknown类型
function parse(input: unknown): User { ... }

// 特定选项使用联合类型
type Status = 'loading' | 'success' | 'error';

// 通用代码使用泛型
function first<T>(arr: T[]): T | undefined { ... }

// 类型断言作为最后手段(需配合运行时检查)
if (isUser(data)) { return data as User; }
tsconfig.json核心配置:
json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true
  }
}

Module Organization

模块组织

Feature-based, not layer-based:
src/
  features/
    auth/
      components/
      hooks/
      api.ts
      types.ts
      index.ts  # Barrel: controlled exports
    orders/
      ...
  shared/
    ui/
    utils/
Use path aliases:
@features/*
,
@shared/*
(avoid
../../../../
).
基于功能而非分层的结构:
src/
  features/
    auth/
      components/
      hooks/
      api.ts
      types.ts
      index.ts  # 桶文件:受控导出
    orders/
      ...
  shared/
    ui/
    utils/
使用路径别名:
@features/*
@shared/*
(避免
../../../../
这种层级引用)。

State Management

状态管理

Server state: TanStack Query exclusively.
typescript
const { data, isLoading, error } = useQuery({
  queryKey: ['user', userId],
  queryFn: () => fetchUser(userId),
});
Client state: Discriminated unions.
typescript
type AuthState =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'authenticated'; user: User }
  | { status: 'error'; error: AppError };
服务端状态:仅使用TanStack Query。
typescript
const { data, isLoading, error } = useQuery({
  queryKey: ['user', userId],
  queryFn: () => fetchUser(userId),
});
客户端状态:使用区分联合类型。
typescript
type AuthState =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'authenticated'; user: User }
  | { status: 'error'; error: AppError };

Async Patterns

异步模式

Always wrap, always context:
typescript
async function fetchUser(id: string): Promise<User> {
  try {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) throw new ApiError(res.status, await res.text());
    return res.json();
  } catch (error) {
    throw new AppError('Failed to fetch user', { cause: error });
  }
}
Cancellation: Use
AbortController
for long operations. Always clean up timeouts in
finally
blocks.
始终进行封装,始终考虑上下文:
typescript
async function fetchUser(id: string): Promise<User> {
  try {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) throw new ApiError(res.status, await res.text());
    return res.json();
  } catch (error) {
    throw new AppError('Failed to fetch user', { cause: error });
  }
}
取消机制:对长时间操作使用
AbortController
。始终在
finally
块中清理超时任务。

Toolchain

工具链

ToolPurpose
pnpmPackage manager (declare in
packageManager
field)
VitestTesting (unit/integration/e2e)
tsupBuilds (ESM + CJS + .d.ts)
ESLintLinting (
@typescript-eslint/no-explicit-any: error
)
PrettierFormatting
工具用途
pnpm包管理器(需在
packageManager
字段中声明)
Vitest测试工具(单元/集成/端到端测试)
tsup构建工具(生成ESM、CJS与.d.ts文件)
ESLint代码检查(设置
@typescript-eslint/no-explicit-any: error
Prettier代码格式化

Anti-Patterns

反模式

  • Type gymnastics (conditional types, template literals without justification)
  • useState
    +
    useEffect
    for server data (use TanStack Query)
  • Technical-layer folders (
    /controllers
    ,
    /services
    ,
    /models
    )
  • eslint-disable
    without documented justification
  • Mocking internal components (mock boundaries only)
  • Mixed package managers or test frameworks
  • 无正当理由使用类型技巧(条件类型、模板字面量类型)
  • 使用
    useState
    +
    useEffect
    处理服务端数据(应使用TanStack Query)
  • 按技术层划分文件夹(如
    /controllers
    /services
    /models
  • 无文档说明理由就使用
    eslint-disable
  • 模拟内部组件(仅模拟边界)
  • 混合使用包管理器或测试框架

References

参考资料

  • toolchain-setup.md - pnpm, Vitest, tsup, ESLint config
  • type-patterns.md - Utility types, generics, guards
  • testing-strategy.md - Test pyramid, behavior focus
  • async-patterns.md - Timeout cleanup, error-specific catch, cancellation
  • toolchain-setup.md - pnpm、Vitest、tsup、ESLint配置
  • type-patterns.md - 工具类型、泛型、类型守卫
  • testing-strategy.md - 测试金字塔、行为聚焦
  • async-patterns.md - 超时清理、特定错误捕获、取消机制