TypeScript 项目内部编码规范详解
TypeScript 作为微软开发的开源编程语言,其自身项目的代码质量直接关系到语言的稳定性和可靠性。本文将深入解析 TypeScript 项目团队内部遵循的编码规范,这些规范虽然主要面向 TypeScript 编译器开发者,但对于普通 TypeScript 开发者也有很高的参考价值。
命名规范
命名是代码可读性的基础,TypeScript 项目对命名有着严格的要求:
-
类型命名:采用 PascalCase(大驼峰式)命名法,如
TypeName
。这与大多数面向对象语言的类命名规范一致。 -
接口命名:明确禁止使用
I
前缀,这是与某些其他语言(如 C#)不同的地方。例如应该使用Props
而非IProps
。 -
枚举值:同样使用 PascalCase,如
enum Color { Red, Green }
。 -
函数和变量:采用 camelCase(小驼峰式)命名法,如
function doSomething() {}
和let myVariable = 1
。 -
私有成员:不同于某些语言使用
_
前缀表示私有成员,TypeScript 项目明确禁止这种做法,而是依赖 TypeScript 的访问修饰符(private/protected)来实现封装。 -
命名完整性:鼓励使用完整的单词而非缩写,如
configuration
优于config
,这有助于提高代码的可读性。
文件组织规范
-
单一职责原则:每个文件应该只包含一个逻辑组件(如解析器、检查器等),这有助于维护和理解代码结构。
-
自动生成文件:任何以
.generated.*
为后缀的文件都是自动生成的,开发者不应手动修改这些文件。
类型系统规范
-
类型导出:只有当类型需要在不同组件间共享时才导出,这有助于减少不必要的依赖。
-
全局命名空间:禁止在全局命名空间中定义类型或值,所有定义都应该在模块内部。
-
共享类型:项目内部共享的类型应该统一放在
types.ts
文件中。 -
类型定义位置:在文件内部,类型定义应该出现在顶部,这样读者可以首先了解数据结构。
null 与 undefined 的选择
项目明确推荐使用 undefined
而非 null
。这一选择简化了类型系统,因为 JavaScript 中许多未定义的值自然就是 undefined
,而 null
需要显式赋值。
不可变性原则
-
核心对象不可变:假设像 Nodes、Symbols 这样的核心对象在定义它们的组件外部是不可变的。
-
数组不可变:同样假设数组是不可变的,这有助于避免意外的副作用。
类与函数的选择
在核心编译链中,项目推荐使用函数闭包而非类。这一选择可能是出于性能考虑,也可能是为了保持函数式编程风格的一致性。
标记属性处理
当一个类型中包含超过 2 个布尔属性时,建议将其转换为标记(flags)。这通常意味着使用枚举或位掩码来表示多个布尔状态的组合。
注释规范
项目要求使用 JSDoc 风格的注释为函数、接口、枚举和类添加文档。这包括:
- 对函数用途的描述
- 参数说明
- 返回值说明
- 可能的异常说明
字符串处理规范
-
引号使用:统一使用双引号
""
而非单引号。 -
国际化:所有展示给用户的字符串信息都需要做好本地化准备,存储在
diagnosticMessages.json
中。
错误提示信息规范
-
语法规范:
- 以句点
.
结尾 - 对不确定的实体使用不定冠词
- 对确切实体使用具体名称
- 以句点
-
语言风格:
- 规则描述时主语使用单数形式
- 使用现在时态
-
错误代码分类:
- 1000-1999:语法信息
- 2000-2999:语言信息
- 4000-4999:声明生成信息
- 5000-5999:编译器选项信息
- 6000-6999:命令行编译器信息
- 7000-7999:noImplicitAny 信息
工具方法规范
-
避免原生方法:项目提供了自己的工具方法(在 core.ts 中),推荐使用这些而非 ECMAScript 5 原生方法。
-
循环处理:
- 禁止使用
for..in
循环 - 推荐使用
ts.forEach
、ts.forEachKey
和ts.forEachValue
- 尽可能使用
ts.forEach
、ts.map
和ts.filter
替代传统循环
- 禁止使用
代码风格细节
-
函数表达式:优先使用箭头函数而非匿名函数表达式。
-
箭头函数参数:
- 单参数时省略括号:
x => x + x
- 多参数或泛型时保留括号:
(x,y) => x + y
或<T>(x: T, y: T) => x === y
- 单参数时省略括号:
-
代码块:
- 总是使用
{}
包裹循环体和条件语句 - 开括号
{
总是与语句在同一行 else
语句在闭括号}
后另起一行
- 总是使用
-
空格规范:
- 小括号内开头不加空格
- 逗号、冒号、分号后加一个空格
- 示例:
for (var i = 0, n = str.length; i < 10; i++) { }
-
变量声明:每个声明语句只声明一个变量,即不使用
var x = 1, y = 2;
的形式。
总结
TypeScript 项目的这些编码规范体现了以下几个核心原则:
- 一致性:统一的命名和代码风格使代码更易于理解和维护。
- 可读性:完整的单词命名、合理的注释和清晰的代码结构都服务于这一目标。
- 可靠性:不可变假设和特定的工具方法选择有助于减少错误。
- 可维护性:严格的类型导出规范和文件组织原则使项目更易于扩展和修改。
虽然这些规范主要是为 TypeScript 编译器开发团队制定的,但其中的许多原则也适用于一般的 TypeScript 开发项目,特别是大型项目或库的开发。理解这些规范背后的思想,可以帮助开发者编写出更专业、更可靠的 TypeScript 代码。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考