关于 no-type-in-docs
这项 TypeScript 技能建议将类型信息保留在类型标注中,不要在注释里重复。它帮助开发者让文档聚焦于代码的目的与意图。
主要功能
- 01避免在注释中重复类型
- 02用注释说明意图
- 03用 JSDoc 说明参数含义
- 04变量名避免包含类型信息
- 05用 readonly 表达不可变约束
适用场景
- 01检查函数注释与 JSDoc
- 02编写 TypeScript API 文档
- 03改进变量命名
- 04避免重复类型标注并阐明代码
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ marius-townhouse/ effective-typescript-skills --skill no-type-in-docs安装后在 Claude Code 中输入/no-type-in-docs确认已加载。
详细介绍
不要在文档中重复类型信息
概述
类型注解就是文档。不要在注释中重复类型信息。
描述类型的注释会与代码脱节。TypeScript 的类型系统设计得简洁易读——请将其作为类型文档的主要来源。
何时使用此技能
- 为函数编写 JSDoc 或注释
- 记录参数类型
- 为变量命名
- 描述返回值
铁律
Never put type information in comments.
Let the type annotations speak for themselves.
请记住:
- 注释会与代码脱节;类型会经过检查
- 类型注解的设计目标就是易读
- 注释应该解释原因,而不是类型是什么
- 变量名不应包含类型信息
检测:注释中的类型信息
/**
* Returns a string with the foreground color.
* Takes zero or one arguments. With no arguments, returns the
* standard foreground color. With one argument, returns the foreground color
* for a particular page.
*/
function getForegroundColor(page?: string) {
return page === 'login' ? {r: 127, g: 127, b: 127} : {r: 0, g: 0, b: 0};
}
问题:
- 注释说“返回一个字符串”,但函数返回的是一个对象
- 注释描述参数数量(签名中一目了然)
- 注释比实现本身还长!
更好的文档
/** Get the foreground color for the application or a specific page. */
function getForegroundColor(page?: string): Color {
// ...
}
类型签名会告诉你:
- 参数是可选字符串
- 返回类型是 Color
- 无需在注释中重复这些信息
不要记录不可变性
// Bad: comment lies (sort() mutates in place)
/** Sort the strings by numeric value. Does not modify nums. */
function sortNumerically(nums: string[]): string[] {
return nums.sort((a, b) => Number(a) - Number(b));
}
// Good: type enforces non-mutation
/** Sort the strings by numeric value. */
function sortNumerically(nums: readonly string[]): string[] {
return nums.toSorted((a, b) => Number(a) - Number(b));
}
TypeScript 会强制执行 readonly 修饰符,而注释不会。
变量名
变量名中不要包含类型信息:
// Bad: redundant type in name
const ageNum = 30;
const nameString = 'Alice';
const usersArray = [];
// Good: descriptive names, types inferred
const age = 30;
const name = 'Alice';
const users = [];
例外:单位
当单位无法从类型中看出时,请将其包含在名称中:
// Good: units aren't captured by type
const timeMs = 1000;
const temperatureC = 20;
const distanceKm = 5.5;
// Better: use branded types (Item 64)
type Milliseconds = number & { _brand: 'ms' };
const time: Milliseconds = 1000 as Milliseconds;
JSDoc 最佳实践
使用 @param 记录参数信息,而非类型信息:
/**
* Formats a user's display name.
* @param user - The user to format
* @param options - Formatting options
* @returns The formatted display name
*/
function formatDisplayName(
user: User,
options?: FormatOptions
): string {
// ...
}
不要重复类型信息:
// Bad: duplicates types
/**
* @param user {User} - The user object
* @param options {FormatOptions | undefined} - Optional formatting options
* @returns {string} The formatted name
*/
注释应该包含的内容
- 用途和意图
- 业务逻辑说明
- 算法描述
- 不明显的行为
- 相关文档链接
/**
* Calculates compound interest using the standard formula.
* See: https://en.wikipedia.org/wiki/Compound_interest
*/
function compoundInterest(
principal: number,
rate: number,
periods: number
): number {
// P(1 + r)^n
return principal * Math.pow(1 + rate, periods);
}
抵御压力守则
1. “注释能让代码更易读”
压力:“我想记录类型,让代码更清晰”
**回应:**类型本身就是文档。它们会经过检查,始终准确。
**行动:**从注释中移除类型信息。如果类型名称不清晰,请改进名称。
2. “我需要记录复杂类型”
压力:“这个类型很复杂,我需要解释一下”
**回应:**在类型定义本身使用 TSDoc。
**行动:**为类型添加文档,而不是为类型的使用位置添加文档。
危险信号——停下来重新考虑
- 注释中提到“返回一个字符串”或类似内容
- 注释中提到参数数量
- 声称“不会修改”(改用 readonly)
numUsers或strName这类变量名
常见自我辩解(都不成立)
| 借口 | 事实 |
|---|---|
| “这样更易读” | 类型本来就设计得易读 |
| “不是所有人都懂 TypeScript” | 他们可以将鼠标悬停在类型上或点击查看 |
| “文档总是有益的” | 过时的文档有害 |
快速参考
// DON'T: Type info in comments
/** Returns string, takes number */
function f(n: number): string { ... }
// DON'T: Claim non-mutation in comments
/** Does not modify array */
function sort(arr: number[]): number[] { ... }
// DON'T: Types in variable names
const ageNum = 30;
// DO: Describe purpose, not types
/** Get display name for UI header */
function getName(user: User): string { ... }
// DO: Use readonly for non-mutation
function sort(arr: readonly number[]): number[] { ... }
// DO: Units in names when helpful
const timeMs = 1000;
总结
类型注解就是文档。
TypeScript 的类型系统表现力强且始终准确。有关类型的注释会与代码脱节,误导读者。请用注释解释用途、意图和业务逻辑,而不是类型。
参考资料
改编自 Dan Vanderkam 的《Effective TypeScript》第 31 条:不要在文档中重复类型信息。
评论
支持 Markdown