关于 typescript-clean-code
typescript-clean-code 是一项参考技能,将 Robert C. Martin 的 Clean Code 原则应用于 TypeScript。它按注释、函数、通用设计、命名和测试组织规范,并提供 TypeScript 专属规则及 AI 审查与编辑要求。
主要功能
- 01将 Clean Code 规范用于 TypeScript
- 02涵盖注释、函数与设计
- 03制定命名和测试指南
- 04补充 TypeScript 专属实践
- 05按规则编号报告违规项
适用场景
- 01依据明确规则审查 TypeScript 代码
- 02指导修改以减少重复和意图不清
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ertugrul-dmr/ clean-code-skills --skill typescript-clean-code安装后在 Claude Code 中输入/typescript-clean-code确认已加载。
详细介绍
Clean TypeScript:完整参考
强制执行 Robert C. Martin 第 17 章中的所有 Clean Code 原则,并针对 TypeScript 进行调整。
注释(C1-C5)
- C1:注释中不写元数据(使用 Git)
- C2:立即删除过时的注释
- C3:不写多余的注释
- C4:如果必须写注释,就要写好
- C5:绝不提交已注释掉的代码
环境(E1-E2)
- E1:使用一条命令进行构建(
npm run build) - E2:使用一条命令运行测试(
npm test)
函数(F1-F4)
- F1:最多 3 个参数(参数更多时使用参数对象/接口)
- F2:不使用输出参数(返回值)
- F3:不使用标志参数(拆分函数)
- F4:删除无用函数
通用原则(G1-G36)
- G1:每个文件只使用一种语言
- G2:实现预期行为
- G3:处理边界条件
- G4:不要覆盖安全防护
- G5:遵循 DRY 原则,不重复
- G6:保持抽象层级一致
- G7:基类不应了解子类
- G8:尽量缩小公共接口
- G9:删除无用代码
- G10:变量应靠近使用位置
- G11:保持一致
- G12:移除杂项
- G13:避免人为耦合
- G14:避免特性嫉妒
- G15:不使用选择器参数
- G16:不要掩盖意图
- G17:在预期的位置编写代码
- G18:优先使用实例方法
- G19:使用解释性变量
- G20:函数名称应说明其功能
- G21:理解算法
- G22:明确依赖关系
- G23:优先使用多态,而非 if/else
- G24:遵循规范(TypeScript 风格指南 + ESLint/Prettier)
- G25:使用命名常量,而非魔法数字
- G26:力求精确
- G27:结构优先于惯例
- G28:封装条件判断
- G29:避免否定条件
- G30:函数只做一件事
- G31:明确时间耦合
- G32:避免随意行事
- G33:封装边界条件
- G34:每个函数只包含一个抽象层级
- G35:在高层配置
- G36:遵循迪米特法则(避免连续调用)
TypeScript 特有原则(TS1-TS3)
这些原则将 Java 特有规则(J1-J3)调整为符合 TypeScript 惯例的形式:
- TS1:保持导入显式且稳定;避免过度使用命名空间风格和隐式依赖
- TS2:使用枚举或字面量联合类型,而非魔法常量
- TS3:明确声明公共接口的类型,并避免在边界处使用
any
命名(N1-N7)
- N1:选择描述性名称
- N2:名称应符合抽象层级
- N3:使用标准术语
- N4:使用明确无歧义的名称
- N5:名称长度应与作用域相匹配
- N6:避免编码式命名
- N7:名称应说明副作用
测试(T1-T9)
- T1:测试所有可能出问题的部分
- T2:使用覆盖率工具
- T3:不要跳过简单测试
- T4:被忽略的测试意味着存在待澄清的问题
- T5:测试边界条件
- T6:针对漏洞附近的情况进行穷尽测试
- T7:从失败中寻找规律
- T8:调试时检查覆盖率
- T9:测试必须快速(每项 < 100ms)
快速参考表
| 类别 | 规则 | 一句话说明 |
|---|---|---|
| 注释 | C1 | 不写元数据(使用 Git) |
| C3 | 不写多余的注释 | |
| C5 | 不写已注释掉的代码 | |
| 函数 | F1 | 最多 3 个参数 |
| F3 | 不使用标志参数 | |
| F4 | 删除无用函数 | |
| 通用原则 | G5 | 遵循 DRY 原则,不重复 |
| G9 | 删除无用代码 | |
| G16 | 不要掩盖意图 | |
| G23 | 优先使用多态,而非 if/else | |
| G25 | 使用命名常量,而非魔法数字 | |
| G30 | 函数只做一件事 | |
| G36 | 遵循迪米特法则(一个点) | |
| 命名 | N1 | 使用描述性名称 |
| N5 | 名称长度应与作用域相匹配 | |
| 测试 | T5 | 测试边界条件 |
| T9 | 测试必须快速 |
反模式(不要这样做 → 应该这样做)
| ❌ 不要这样做 | ✅ 应该这样做 |
|---|---|
| 注释每一行代码 | 删除显而易见的注释 |
| 为一行代码编写辅助函数 | 将代码内联 |
到处使用 import * as utils | 使用命名导入,明确依赖项 |
在公共 API 中使用 any | 使用具体类型,或使用 unknown 并进行收窄 |
魔法数字 86400 | const SECONDS_PER_DAY = 86400 |
process(data, true) | processVerbose(data) |
| 深层嵌套 | 使用守卫子句,尽早返回 |
obj.a.b.c.value | obj.getValue() |
| 超过 100 行的函数 | 按职责拆分 |
AI 行为
审查代码时,按规则编号指出违规项(例如:“违反 G5:逻辑重复”)。
修复或编辑代码时,说明修复内容(例如:“已修复:将魔法数字提取为 SECONDS_PER_DAY(G25)”)。
评论
支持 Markdown