typescript-pro

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TypeScript Pro Specialist

TypeScript资深专家

Purpose

定位

Provides expert TypeScript development capabilities with advanced type system features, generic programming patterns, and type-safe application architecture. Specializes in leveraging TypeScript 5+ for building robust, maintainable applications with comprehensive type safety.
提供具备高级类型系统特性、泛型编程模式和类型安全应用架构的专业TypeScript开发能力。专注于利用TypeScript 5+构建具备全面类型安全、健壮且可维护的应用。

When to Use

适用场景

  • Designing complex type systems with advanced generics and mapped types
  • Implementing type-safe APIs across frontend-backend boundaries
  • Migrating JavaScript codebases to TypeScript gradually
  • Troubleshooting complex type errors or inference issues
  • Building type-safe libraries, SDKs, or framework integrations
  • Optimizing TypeScript build performance in large projects
  • Creating branded types, discriminated unions, and utility types
  • 设计包含高级泛型和映射类型的复杂类型系统
  • 实现跨前后端边界的类型安全API
  • 逐步将JavaScript代码库迁移到TypeScript
  • 排查复杂的类型错误或类型推断问题
  • 构建类型安全的库、SDK或框架集成
  • 优化大型项目中的TypeScript构建性能
  • 创建品牌类型、可辨识联合类型和工具类型

Quick Start

快速开始

Invoke this skill when:
  • Designing complex type systems with advanced generics and mapped types
  • Implementing type-safe APIs across frontend-backend boundaries
  • Migrating JavaScript codebases to TypeScript gradually
  • Troubleshooting complex type errors or inference issues
  • Building type-safe libraries, SDKs, or framework integrations
Do NOT invoke when:
  • Simple JavaScript tasks (type annotations not needed)
  • Runtime logic bugs (use debugger instead)
  • Build configuration only (use build-engineer instead)
  • React/Vue-specific patterns (use react-specialist/vue-expert)


当以下情况时调用该技能:
  • 设计包含高级泛型和映射类型的复杂类型系统
  • 实现跨前后端边界的类型安全API
  • 逐步将JavaScript代码库迁移到TypeScript
  • 排查复杂的类型错误或类型推断问题
  • 构建类型安全的库、SDK或框架集成
以下情况请勿调用:
  • 简单JavaScript任务(无需类型注解)
  • 运行时逻辑bug(请使用调试器)
  • 仅涉及构建配置(请使用构建工程师技能)
  • React/Vue特定模式(请使用react-specialist/vue-expert技能)


Core Workflows

核心工作流

Workflow 1: Design Type-Safe API Client

工作流1:设计类型安全的API客户端

Use case: Create fully type-safe REST API client with auto-completion
Steps:
1. Define API Schema (Contract-First)
typescript
// api-schema.ts - Single source of truth for API contract
export const apiSchema = {
  '/users': {
    GET: {
      query: {} as { page?: number; limit?: number },
      response: {} as { users: User[]; total: number }
    },
    POST: {
      body: {} as { email: string; name: string },
      response: {} as { id: string; email: string; name: string }
    }
  },
  '/users/{id}': {
    GET: {
      params: {} as { id: string },
      response: {} as User
    },
    PUT: {
      params: {} as { id: string },
      body: {} as Partial<User>,
      response: {} as User
    },
    DELETE: {
      params: {} as { id: string },
      response: {} as { success: boolean }
    }
  },
  '/posts': {
    GET: {
      query: {} as { author_id?: string; tags?: string[] },
      response: {} as { posts: Post[]; next_cursor?: string }
    }
  }
} as const;

// Extract types from schema
type ApiSchema = typeof apiSchema;
type ApiPaths = keyof ApiSchema;
type ApiMethods<Path extends ApiPaths> = keyof ApiSchema[Path];

// Helper types for type-safe request/response
type RequestParams<
  Path extends ApiPaths,
  Method extends ApiMethods<Path>
> = ApiSchema[Path][Method] extends { params: infer P } ? P : never;

type RequestQuery<
  Path extends ApiPaths,
  Method extends ApiMethods<Path>
> = ApiSchema[Path][Method] extends { query: infer Q } ? Q : never;

type RequestBody<
  Path extends ApiPaths,
  Method extends ApiMethods<Path>
> = ApiSchema[Path][Method] extends { body: infer B } ? B : never;

type ResponseData<
  Path extends ApiPaths,
  Method extends ApiMethods<Path>
> = ApiSchema[Path][Method] extends { response: infer R } ? R : never;
2. Implement Type-Safe API Client
typescript
// api-client.ts
class ApiClient {
  constructor(private baseUrl: string) {}

  async request<
    Path extends ApiPaths,
    Method extends ApiMethods<Path>
  >(
    path: Path,
    method: Method,
    options?: {
      params?: RequestParams<Path, Method>;
      query?: RequestQuery<Path, Method>;
      body?: RequestBody<Path, Method>;
    }
  ): Promise<ResponseData<Path, Method>> {
    // Replace path parameters: /users/{id} → /users/123
    let url = path as string;
    if (options?.params) {
      Object.entries(options.params).forEach(([key, value]) => {
        url = url.replace(`{${key}}`, String(value));
      });
    }

    // Append query parameters
    if (options?.query) {
      const queryString = new URLSearchParams(
        options.query as Record<string, string>
      ).toString();
      url += `?${queryString}`;
    }

    // Make request
    const response = await fetch(`${this.baseUrl}${url}`, {
      method: method as string,
      headers: {
        'Content-Type': 'application/json',
      },
      body: options?.body ? JSON.stringify(options.body) : undefined,
    });

    if (!response.ok) {
      throw new Error(`API Error: ${response.status}`);
    }

    return response.json();
  }
}

// Usage with full type safety and auto-completion
const api = new ApiClient('https://api.example.com');

// GET /users?page=1&limit=10
const usersResponse = await api.request('/users', 'GET', {
  query: { page: 1, limit: 10 }  // Type-checked!
});
usersResponse.users[0].email;  // ✅ Auto-complete works!

// POST /users
const newUser = await api.request('/users', 'POST', {
  body: { email: 'test@example.com', name: 'Test' }  // Type-checked!
});
newUser.id;  // ✅ Type: string

// PUT /users/{id}
const updatedUser = await api.request('/users/{id}', 'PUT', {
  params: { id: '123' },  // Type-checked!
  body: { name: 'Updated Name' }  // Partial<User> type-checked!
});

// TypeScript errors for invalid usage:
api.request('/users', 'GET', {
  query: { invalid: true }  // ❌ Error: Object literal may only specify known properties
});

api.request('/users/{id}', 'PUT', {
  // ❌ Error: params required for this path
  body: { name: 'Test' }
});
3. Add Runtime Validation with Zod
typescript
import { z } from 'zod';

// Define Zod schemas for runtime validation
const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string().min(1).max(100),
  created_at: z.string().datetime()
});

type User = z.infer<typeof UserSchema>;  // TypeScript type from Zod schema

// Enhanced API client with runtime validation
class ValidatedApiClient extends ApiClient {
  async request<
    Path extends ApiPaths,
    Method extends ApiMethods<Path>
  >(
    path: Path,
    method: Method,
    options?: {
      params?: RequestParams<Path, Method>;
      query?: RequestQuery<Path, Method>;
      body?: RequestBody<Path, Method>;
      responseSchema?: z.ZodSchema<ResponseData<Path, Method>>;
    }
  ): Promise<ResponseData<Path, Method>> {
    const response = await super.request(path, method, options);

    // Runtime validation if schema provided
    if (options?.responseSchema) {
      return options.responseSchema.parse(response);
    }

    return response;
  }
}

// Usage with runtime validation
const validatedApi = new ValidatedApiClient('https://api.example.com');

const user = await validatedApi.request('/users/{id}', 'GET', {
  params: { id: '123' },
  responseSchema: UserSchema  // Runtime validation!
});
// If API returns invalid data, Zod throws detailed error


使用场景: 创建具备自动补全功能的完全类型安全的REST API客户端
步骤:
1. 定义API Schema(契约优先)
typescript
// api-schema.ts - API契约的单一可信源
export const apiSchema = {
  '/users': {
    GET: {
      query: {} as { page?: number; limit?: number },
      response: {} as { users: User[]; total: number }
    },
    POST: {
      body: {} as { email: string; name: string },
      response: {} as { id: string; email: string; name: string }
    }
  },
  '/users/{id}': {
    GET: {
      params: {} as { id: string },
      response: {} as User
    },
    PUT: {
      params: {} as { id: string },
      body: {} as Partial<User>,
      response: {} as User
    },
    DELETE: {
      params: {} as { id: string },
      response: {} as { success: boolean }
    }
  },
  '/posts': {
    GET: {
      query: {} as { author_id?: string; tags?: string[] },
      response: {} as { posts: Post[]; next_cursor?: string }
    }
  }
} as const;

// 从Schema中提取类型
type ApiSchema = typeof apiSchema;
type ApiPaths = keyof ApiSchema;
type ApiMethods<Path extends ApiPaths> = keyof ApiSchema[Path];

// 用于类型安全请求/响应的辅助类型
type RequestParams<
  Path extends ApiPaths,
  Method extends ApiMethods<Path>
> = ApiSchema[Path][Method] extends { params: infer P } ? P : never;

type RequestQuery<
  Path extends ApiPaths,
  Method extends ApiMethods<Path>
> = ApiSchema[Path][Method] extends { query: infer Q } ? Q : never;

type RequestBody<
  Path extends ApiPaths,
  Method extends ApiMethods<Path>
> = ApiSchema[Path][Method] extends { body: infer B } ? B : never;

type ResponseData<
  Path extends ApiPaths,
  Method extends ApiMethods<Path>
> = ApiSchema[Path][Method] extends { response: infer R } ? R : never;
2. 实现类型安全的API客户端
typescript
// api-client.ts
class ApiClient {
  constructor(private baseUrl: string) {}

  async request<
    Path extends ApiPaths,
    Method extends ApiMethods<Path>
  >(
    path: Path,
    method: Method,
    options?: {
      params?: RequestParams<Path, Method>;
      query?: RequestQuery<Path, Method>;
      body?: RequestBody<Path, Method>;
    }
  ): Promise<ResponseData<Path, Method>> {
    // 替换路径参数:/users/{id} → /users/123
    let url = path as string;
    if (options?.params) {
      Object.entries(options.params).forEach(([key, value]) => {
        url = url.replace(`{${key}}`, String(value));
      });
    }

    // 追加查询参数
    if (options?.query) {
      const queryString = new URLSearchParams(
        options.query as Record<string, string>
      ).toString();
      url += `?${queryString}`;
    }

    // 发起请求
    const response = await fetch(`${this.baseUrl}${url}`, {
      method: method as string,
      headers: {
        'Content-Type': 'application/json',
      },
      body: options?.body ? JSON.stringify(options.body) : undefined,
    });

    if (!response.ok) {
      throw new Error(`API Error: ${response.status}`);
    }

    return response.json();
  }
}

// 具备完全类型安全和自动补全的使用示例
const api = new ApiClient('https://api.example.com');

// GET /users?page=1&limit=10
const usersResponse = await api.request('/users', 'GET', {
  query: { page: 1, limit: 10 }  // 类型校验通过!
});
usersResponse.users[0].email;  // ✅ 自动补全生效!

// POST /users
const newUser = await api.request('/users', 'POST', {
  body: { email: 'test@example.com', name: 'Test' }  // 类型校验通过!
});
newUser.id;  // ✅ 类型:string

// PUT /users/{id}
const updatedUser = await api.request('/users/{id}', 'PUT', {
  params: { id: '123' },  // 类型校验通过!
  body: { name: 'Updated Name' }  // Partial<User>类型校验通过!
});

// 无效用法的TypeScript错误:
api.request('/users', 'GET', {
  query: { invalid: true }  // ❌ 错误:对象字面量只能指定已知属性
});

api.request('/users/{id}', 'PUT', {
  // ❌ 错误:该路径需要params参数
  body: { name: 'Test' }
});
3. 结合Zod添加运行时验证
typescript
import { z } from 'zod';

// 定义用于运行时验证的Zod Schema
const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string().min(1).max(100),
  created_at: z.string().datetime()
});

type User = z.infer<typeof UserSchema>;  // 从Zod Schema生成TypeScript类型

// 增强型带运行时验证的API客户端
class ValidatedApiClient extends ApiClient {
  async request<
    Path extends ApiPaths,
    Method extends ApiMethods<Path>
  >(
    path: Path,
    method: Method,
    options?: {
      params?: RequestParams<Path, Method>;
      query?: RequestQuery<Path, Method>;
      body?: RequestBody<Path, Method>;
      responseSchema?: z.ZodSchema<ResponseData<Path, Method>>;
    }
  ): Promise<ResponseData<Path, Method>> {
    const response = await super.request(path, method, options);

    // 如果提供了Schema则进行运行时验证
    if (options?.responseSchema) {
      return options.responseSchema.parse(response);
    }

    return response;
  }
}

// 带运行时验证的使用示例
const validatedApi = new ValidatedApiClient('https://api.example.com');

const user = await validatedApi.request('/users/{id}', 'GET', {
  params: { id: '123' },
  responseSchema: UserSchema  // 运行时验证!
});
// 如果API返回无效数据,Zod会抛出详细错误


Workflow 3: Gradual TypeScript Migration

工作流3:TypeScript逐步迁移

Use case: Migrate large JavaScript codebase incrementally
Phase 1: Enable TypeScript with Zero Changes (Week 1)
json
// tsconfig.json - Initial configuration
{
  "compilerOptions": {
    "allowJs": true,          // Allow .js files
    "checkJs": false,         // Don't check .js files yet
    "noEmit": true,           // Don't output files (just check)
    "skipLibCheck": true,     // Skip type checking of .d.ts files
    "esModuleInterop": true,
    "moduleResolution": "node",
    "target": "ES2017",
    "module": "commonjs"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
Phase 2: Add JSDoc Type Hints (Weeks 2-4)
javascript
// user.js - Add JSDoc comments for type checking
/**
 * @typedef {Object} User
 * @property {string} id
 * @property {string} email
 * @property {string} name
 */

/**
 * Fetch user by ID
 * @param {string} userId
 * @returns {Promise<User>}
 */
async function getUserById(userId) {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
}

/**
 * @param {User[]} users
 * @param {string} searchTerm
 * @returns {User[]}
 */
function filterUsers(users, searchTerm) {
  return users.filter(u => u.name.includes(searchTerm));
}
Phase 3: Enable checkJs Gradually (Weeks 5-8)
json
// tsconfig.json - Start checking JavaScript
{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true,  // ✅ Enable type checking for .js files
    "noEmit": true
  }
}
Fix errors directory by directory:
bash
undefined
使用场景: 逐步迁移大型JavaScript代码库
阶段1:零改动启用TypeScript(第1周)
json
// tsconfig.json - 初始配置
{
  "compilerOptions": {
    "allowJs": true,          // 允许.js文件
    "checkJs": false,         // 暂不检查.js文件
    "noEmit": true,           // 不输出文件(仅做检查)
    "skipLibCheck": true,     // 跳过.d.ts文件的类型检查
    "esModuleInterop": true,
    "moduleResolution": "node",
    "target": "ES2017",
    "module": "commonjs"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
阶段2:添加JSDoc类型提示(第2-4周)
javascript
// user.js - 添加JSDoc注释以支持类型检查
/**
 * @typedef {Object} User
 * @property {string} id
 * @property {string} email
 * @property {string} name
 */

/**
 * 根据ID获取用户
 * @param {string} userId
 * @returns {Promise<User>}
 */
async function getUserById(userId) {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
}

/**
 * @param {User[]} users
 * @param {string} searchTerm
 * @returns {User[]}
 */
function filterUsers(users, searchTerm) {
  return users.filter(u => u.name.includes(searchTerm));
}
阶段3:逐步启用checkJs(第5-8周)
json
// tsconfig.json - 开始检查JavaScript文件
{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true,  // ✅ 启用.js文件的类型检查
    "noEmit": true
  }
}
按目录修复错误:
bash
undefined

Disable checkJs for specific files with errors

对有错误的特定文件禁用checkJs

// @ts-nocheck at top of file
// 在文件顶部添加@ts-nocheck

Or suppress specific errors

或者抑制特定错误

// @ts-ignore const result = unsafeOperation();

**Phase 4: Rename Files to TypeScript (Weeks 9-12)**
```bash
// @ts-ignore const result = unsafeOperation();

**阶段4:将文件重命名为TypeScript(第9-12周)**
```bash

Rename .js → .ts one directory at a time

逐个目录将.js重命名为.ts

mv src/utils/user.js src/utils/user.ts
mv src/utils/user.js src/utils/user.ts

Update imports (no file extensions in TypeScript)

更新导入(TypeScript中无需文件扩展名)

  • import { getUserById } from './user.js'
  • import { getUserById } from './user'

**Add explicit types:**
```typescript
// user.ts - Full TypeScript with explicit types
interface User {
  id: string;
  email: string;
  name: string;
  created_at: Date;
}

async function getUserById(userId: string): Promise<User> {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
}

function filterUsers(users: User[], searchTerm: string): User[] {
  return users.filter(u => u.name.includes(searchTerm));
}
Phase 5: Enable Strict Mode (Weeks 13-16)
json
// tsconfig.json - Enable strict mode progressively
{
  "compilerOptions": {
    "strict": true,  // Enable all strict checks
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true
  }
}
Fix strict mode errors:
typescript
// Before (implicit any)
function processData(data) {  // ❌ Parameter 'data' implicitly has 'any' type
  return data.map(item => item.value);
}

// After (explicit types)
function processData(data: Array<{ value: number }>): number[] {
  return data.map(item => item.value);
}

// Before (null not handled)
function getUserName(user: User) {  // ❌ User might be null
  return user.name;
}

// After (null handled)
function getUserName(user: User | null): string {
  return user?.name ?? 'Unknown';
}


  • import { getUserById } from './user.js'
  • import { getUserById } from './user'

**添加显式类型:**
```typescript
// user.ts - 带显式类型的完整TypeScript代码
interface User {
  id: string;
  email: string;
  name: string;
  created_at: Date;
}

async function getUserById(userId: string): Promise<User> {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
}

function filterUsers(users: User[], searchTerm: string): User[] {
  return users.filter(u => u.name.includes(searchTerm));
}
阶段5:启用严格模式(第13-16周)
json
// tsconfig.json - 逐步启用严格模式
{
  "compilerOptions": {
    "strict": true,  // 启用所有严格检查
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true
  }
}
修复严格模式错误:
typescript
// 之前(隐式any)
function processData(data) {  // ❌ 参数'data'隐式拥有'any'类型
  return data.map(item => item.value);
}

// 之后(显式类型)
function processData(data: Array<{ value: number }>): number[] {
  return data.map(item => item.value);
}

// 之前(未处理null)
function getUserName(user: User) {  // ❌ User可能为null
  return user.name;
}

// 之后(处理null)
function getUserName(user: User | null): string {
  return user?.name ?? 'Unknown';
}


Pattern 2: Template Literal Types for String Validation

模式2:用于字符串验证的模板字面量类型

When to use: CSS class names, API routes, environment variables
typescript
// Type-safe CSS class names
type Size = 'sm' | 'md' | 'lg';
type Color = 'red' | 'blue' | 'green';
type ClassName = `btn-${Size}-${Color}`;

function createButton(className: ClassName) {
  return `<button class="${className}"></button>`;
}

createButton('btn-md-blue');  // ✅ Valid
createButton('btn-xl-yellow');  // ❌ Error: Not assignable to ClassName

// Type-safe environment variables
type Stage = 'dev' | 'staging' | 'prod';
type Region = 'us' | 'eu' | 'asia';
type Environment = `${Stage}_${Region}`;

const env: Environment = 'prod_us';  // ✅ Valid
const invalid: Environment = 'production_us';  // ❌ Error


适用场景: CSS类名、API路由、环境变量
typescript
// 类型安全的CSS类名
type Size = 'sm' | 'md' | 'lg';
type Color = 'red' | 'blue' | 'green';
type ClassName = `btn-${Size}-${Color}`;

function createButton(className: ClassName) {
  return `<button class="${className}"></button>`;
}

createButton('btn-md-blue');  // ✅ 有效
createButton('btn-xl-yellow');  // ❌ 错误:无法赋值给ClassName

// 类型安全的环境变量
type Stage = 'dev' | 'staging' | 'prod';
type Region = 'us' | 'eu' | 'asia';
type Environment = `${Stage}_${Region}`;

const env: Environment = 'prod_us';  // ✅ 有效
const invalid: Environment = 'production_us';  // ❌ 错误


❌ Anti-Pattern 2: Not Defining Return Types

❌ 反模式2:未定义返回类型

What it looks like:
typescript
function getUser(id: string) {  // ❌ No return type
  return fetch(`/api/users/${id}`).then(r => r.json());
}
// Return type inferred as Promise<any>
Why it fails:
  • Return type changes silently if implementation changes
  • No guarantee of what function returns
  • Harder to catch breaking changes
Correct approach:
typescript
interface User {
  id: string;
  email: string;
  name: string;
}

function getUser(id: string): Promise<User> {  // ✅ Explicit return type
  return fetch(`/api/users/${id}`).then(r => r.json());
}


示例:
typescript
function getUser(id: string) {  // ❌ 无返回类型
  return fetch(`/api/users/${id}`).then(r => r.json());
}
// 返回类型被推断为Promise<any>
问题原因:
  • 若实现变更,返回类型会静默改变
  • 无法保证函数返回值的类型
  • 难以捕获破坏性变更
正确做法:
typescript
interface User {
  id: string;
  email: string;
  name: string;
}

function getUser(id: string): Promise<User> {  // ✅ 显式返回类型
  return fetch(`/api/users/${id}`).then(r => r.json());
}


Integration Patterns

集成模式

typescript-pro ↔ react-specialist

typescript-pro ↔ react-specialist

  • Handoff: TypeScript pro defines types → React specialist uses in components
  • Collaboration: Shared type definitions for props, state, API contracts
  • Tools: TypeScript for types, React for UI logic
  • 交接:TypeScript专家定义类型 → React专家在组件中使用
  • 协作:共享props、状态、API契约的类型定义
  • 工具:TypeScript用于类型定义,React用于UI逻辑

typescript-pro ↔ backend-developer

typescript-pro ↔ backend-developer

  • Handoff: TypeScript pro designs API types → Backend implements matching types
  • Collaboration: Shared schema definitions (OpenAPI, tRPC, GraphQL)
  • Shared responsibility: End-to-end type safety
  • 交接:TypeScript专家设计API类型 → 后端实现匹配的类型
  • 协作:共享Schema定义(OpenAPI、tRPC、GraphQL)
  • 共同责任:端到端类型安全

typescript-pro ↔ nextjs-developer

typescript-pro ↔ nextjs-developer

  • Handoff: TypeScript types → Next.js App Router Server/Client Components
  • Collaboration: Server Actions types, API route types
  • Dependency: Next.js benefits heavily from TypeScript

  • 交接:TypeScript类型 → Next.js App Router服务端/客户端组件
  • 协作:Server Actions类型、API路由类型
  • 依赖:Next.js极大受益于TypeScript