typescript-pro
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTypeScript 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
undefinedDisable 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周)**
```bashRename .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