typescript-pro
SKILL.md
TypeScript 专家
深度掌握 TypeScript 5.0+ 高级类型系统,构建零运行时类型错误的应用。
使用内置工具
read_file— 阅读现有 TypeScript 代码和类型定义edit_file— 添加/修改类型注解、重构类型定义run_command—npx tsc --noEmit(类型检查)、npx tsc --showConfig(查看配置)grep— 搜索any类型使用、缺少类型注解的位置
高级类型模式
泛型约束
// 约束泛型参数必须有 id 属性
function getById<T extends { id: string }>(items: T[], id: string): T | undefined {
return items.find(item => item.id === id);
}
// 键约束:K 必须是 T 的键
function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
const result = {} as Pick<T, K>;
keys.forEach(key => { result[key] = obj[key]; });
return result;
}
条件类型
// 根据输入类型推导返回类型
type ApiResponse<T> = T extends string
? { message: T }
: T extends object
? { data: T }
: { value: T };
// 提取 Promise 内部类型
type Awaited<T> = T extends Promise<infer U> ? Awaited<U> : T;
// 提取函数返回类型中的非 undefined 部分
type NonNullableReturn<T extends (...args: any[]) => any> =
NonNullable<ReturnType<T>>;
模板字面量类型
type EventName = `on${Capitalize<'click' | 'focus' | 'blur'>}`;
// → 'onClick' | 'onFocus' | 'onBlur'
type CSSProperty = `${string}-${string}`;
type HTTPMethod = `${'GET' | 'POST' | 'PUT' | 'DELETE'}`;
// API 路由类型安全
type ApiRoute = `/api/v1/${'users' | 'orders' | 'products'}`;
Branded Types(品牌类型)
// 防止不同 ID 类型混用
type UserId = string & { readonly __brand: 'UserId' };
type OrderId = string & { readonly __brand: 'OrderId' };
function createUserId(id: string): UserId {
return id as UserId;
}
function getUser(id: UserId): User { /* ... */ }
function getOrder(id: OrderId): Order { /* ... */ }
const userId = createUserId('abc');
getUser(userId); // ✅
// getOrder(userId); // ❌ 编译错误!类型不兼容
类型守卫
// 类型谓词
function isString(value: unknown): value is string {
return typeof value === 'string';
}
// 断言函数
function assertDefined<T>(value: T | null | undefined, message?: string): asserts value is T {
if (value == null) {
throw new Error(message ?? 'Value is null or undefined');
}
}
// 判别联合类型
type Result<T> =
| { success: true; data: T }
| { success: false; error: string };
function handleResult<T>(result: Result<T>) {
if (result.success) {
console.log(result.data); // TypeScript 知道这里是 { data: T }
} else {
console.error(result.error); // TypeScript 知道这里是 { error: string }
}
}
判别联合(状态机)
type RequestState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: T }
| { status: 'error'; error: Error };
function render<T>(state: RequestState<T>) {
switch (state.status) {
case 'idle': return '等待开始';
case 'loading': return '加载中...';
case 'success': return `数据: ${JSON.stringify(state.data)}`;
case 'error': return `错误: ${state.error.message}`;
}
}
Mapped Types(映射类型)
// 将所有属性变为可选且可为 null
type NullablePartial<T> = {
[K in keyof T]?: T[K] | null;
};
// 从类型中提取所有方法
type Methods<T> = {
[K in keyof T as T[K] extends (...args: any[]) => any ? K : never]: T[K];
};
// 为事件添加 on 前缀
type EventHandlers<T> = {
[K in keyof T as `on${Capitalize<string & K>}`]: (value: T[K]) => void;
};
satisfies 操作符(TypeScript 4.9+)
// 验证类型但保留推断的字面量类型
const config = {
port: 3000,
host: 'localhost',
debug: true,
} satisfies Record<string, string | number | boolean>;
// config.port 的类型是 3000(而非 number)
// config.host 的类型是 'localhost'(而非 string)
const 断言
// as const 使值成为字面量类型
const COLORS = {
red: '#ff0000',
green: '#00ff00',
blue: '#0000ff',
} as const;
type Color = typeof COLORS[keyof typeof COLORS];
// → '#ff0000' | '#00ff00' | '#0000ff'
// 优于 enum 的模式
const Status = {
Active: 'active',
Inactive: 'inactive',
Pending: 'pending',
} as const;
type Status = typeof Status[keyof typeof Status];
常用工具类型速查
| 工具类型 | 作用 | 示例 |
|---|---|---|
Partial<T> |
所有属性可选 | Partial<User> |
Required<T> |
所有属性必需 | Required<Config> |
Readonly<T> |
所有属性只读 | Readonly<State> |
Pick<T, K> |
选取部分属性 | Pick<User, 'id' | 'name'> |
Omit<T, K> |
排除部分属性 | Omit<User, 'password'> |
Record<K, V> |
键值映射 | Record<string, number> |
Exclude<T, U> |
从联合中排除 | Exclude<Status, 'deleted'> |
Extract<T, U> |
从联合中提取 | Extract<Event, { type: 'click' }> |
NonNullable<T> |
排除 null/undefined | NonNullable<string | null> |
ReturnType<T> |
函数返回类型 | ReturnType<typeof fn> |
Parameters<T> |
函数参数类型 | Parameters<typeof fn> |
Awaited<T> |
解包 Promise | Awaited<Promise<string>> |
tsconfig 最佳实践
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"exactOptionalPropertyTypes": true,
"forceConsistentCasingInFileNames": true,
"verbatimModuleSyntax": true,
"isolatedModules": true,
"skipLibCheck": true,
"moduleResolution": "bundler",
"module": "ESNext",
"target": "ES2022"
}
}
编码原则
必须做
- 启用 strict 模式及所有编译器标志
- 使用类型优先的 API 设计
- 为领域建模使用 Branded Types
- 使用
satisfies操作符验证类型 - 使用判别联合实现状态机
- 优化类型推导(减少显式注解)
绝不做
- 无理由使用
any(用unknown替代) - 跳过公共 API 的类型定义
- 混合 type-only 和值导入
- 禁用 strict null checks
- 无必要使用
as类型断言 - 使用
enum(优先用as const对象)
知识参考
TypeScript 5.0+、泛型、条件类型、映射类型、模板字面量类型、判别联合、类型守卫、Branded Types、tRPC、项目引用、增量编译、声明文件、const 断言、satisfies 操作符
Weekly Installs
1
Repository
senweaver/senweaver-ideGitHub Stars
15
First Seen
13 days ago
Security Audits
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1