关于 typescript-pro
typescript-pro 面向 TypeScript 开发者,涵盖复杂类型设计、类型安全 API 和 JavaScript 迁移。它提供类型问题排查及大型项目构建性能方面的工作流指导。
主要功能
- 01高级泛型与映射类型
- 02类型安全 API 设计
- 03渐进式 JavaScript 迁移
- 04类型错误与推断问题排查
- 05TypeScript 构建性能指导
适用场景
- 01设计可复用的类型系统
- 02在应用层之间共享 API 类型
- 03迁移大型 JavaScript 代码库
- 04诊断复杂编译器错误
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ 404kidwiz/ claude-supercode-skills --skill typescript-pro安装后在 Claude Code 中输入/typescript-pro确认已加载。
详细介绍
TypeScript 专家
用途
提供专业的 TypeScript 开发能力,涵盖高级类型系统特性、泛型编程模式和类型安全的应用架构。专注于运用 TypeScript 5+ 构建健壮、易于维护且具备全面类型安全性的应用。
适用场景
- 使用高级泛型和映射类型设计复杂的类型系统
- 在前后端边界实现类型安全的 API
- 逐步将 JavaScript 代码库迁移到 TypeScript
- 排查复杂的类型错误或类型推断问题
- 构建类型安全的库、SDK 或框架集成
- 优化大型项目中的 TypeScript 构建性能
- 创建品牌类型、可辨识联合类型和工具类型
快速开始
适用于以下场景:
- 使用高级泛型和映射类型设计复杂的类型系统
- 在前后端边界实现类型安全的 API
- 逐步将 JavaScript 代码库迁移到 TypeScript
- 排查复杂的类型错误或类型推断问题
- 构建类型安全的库、SDK 或框架集成
以下场景请勿使用:
- 简单的 JavaScript 任务(无需类型注解)
- 运行时逻辑错误(改用调试器)
- 仅涉及构建配置(改用 build-engineer)
- React/Vue 专属模式(改用 react-specialist/vue-expert)
核心工作流
工作流 1:设计类型安全的 API 客户端
适用场景: 创建具备自动补全功能的完全类型安全 REST API 客户端
步骤:
1. 定义 API 架构(契约优先)
// 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. 实现类型安全的 API 客户端
// 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: '[email protected]', 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. 使用 Zod 添加运行时验证
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
工作流 3:逐步迁移到 TypeScript
适用场景: 逐步迁移大型 JavaScript 代码库
阶段 1:启用 TypeScript,不做任何改动(第 1 周)
// 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"]
}
阶段 2:添加 JSDoc 类型提示(第 2–4 周)
// 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));
}
阶段 3:逐步启用 checkJs(第 5–8 周)
// tsconfig.json - Start checking JavaScript
{
"compilerOptions": {
"allowJs": true,
"checkJs": true, // ✅ Enable type checking for .js files
"noEmit": true
}
}
按目录逐一修复错误:
# Disable checkJs for specific files with errors
// @ts-nocheck at top of file
# Or suppress specific errors
// @ts-ignore
const result = unsafeOperation();
阶段 4:将文件重命名为 TypeScript 文件(第 9–12 周)
# Rename .js → .ts one directory at a time
mv src/utils/user.js src/utils/user.ts
# Update imports (no file extensions in TypeScript)
- import { getUserById } from './user.js'
+ import { getUserById } from './user'
添加显式类型:
// 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));
}
阶段 5:启用严格模式(第 13–16 周)
// tsconfig.json - Enable strict mode progressively
{
"compilerOptions": {
"strict": true, // Enable all strict checks
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true
}
}
修复严格模式错误:
// 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';
}
模式 2:使用模板字面量类型验证字符串
适用场景: CSS 类名、API 路由、环境变量
// 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
❌ 反模式 2:不定义返回类型
表现形式:
function getUser(id: string) { // ❌ No return type
return fetch(`/api/users/${id}`).then(r => r.json());
}
// Return type inferred as Promise<any>
问题所在:
- 实现发生变化时,返回类型会悄然改变
- 无法保证函数的返回内容
- 更难发现破坏性变更
正确做法:
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-pro ↔ react-specialist
- 交接: TypeScript 专家定义类型 → React 专家在组件中使用这些类型
- 协作: 共享 props、状态和 API 契约的类型定义
- 工具: 使用 TypeScript 定义类型,使用 React 实现 UI 逻辑
typescript-pro ↔ backend-developer
- 交接: TypeScript 专家设计 API 类型 → 后端开发者实现匹配的类型
- 协作: 共享架构定义(OpenAPI、tRPC、GraphQL)
- 共同职责: 端到端类型安全
typescript-pro ↔ nextjs-developer
- 交接: TypeScript 类型 → Next.js App Router 服务端/客户端组件
- 协作: Server Actions 类型、API 路由类型
- 依赖关系: Next.js 可从 TypeScript 中受益匪浅
评论
支持 Markdown