TypeScript编码规范
1 代码风格
1.1 文件
[建议] TypeScript 文件使用无 BOM 的 UTF-8 编码。
UTF-8 编码具有更广泛的适应性。BOM 在使用程序或工具处理文件时可能造成不必要的干扰。
1.2 结构
1.2.1 缩进
[强制] 使用 4 个空格做为一个缩进层级
[强制] switch 下的 case 和 default 必须增加一个缩进层级。
1.2.2 空格
[强制] 二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格。
[强制] if/else/for/while/function/switch/do/try/catch/finally 关键字后,必须有一个空格。
[强制] 在对象创建时,属性中的 : 之后必须有空格,: 之前不允许有空格。
[强制] 函数声明、具名函数表达式、函数调用中,函数名和 ( 之间不允许有空格。
[强制] 在函数调用、函数声明、括号表达式、属性访问、if/for/while/switch/catch 等语句中,() 和 [] 内紧贴括号部分不允许有空格。
[强制] 行尾不得有多余的空格。
1.2.3 换行
[强制] 每个独立语句结束后必须换行。
[强制] 运算符处换行时,运算符必须在新行的行首。
[建议] 不同行为或逻辑的语句集,使用空行隔开,更易阅读。
[建议] 在语句的行字符串长度超过 120 时,根据逻辑条件合理缩进。
[建议] 对于 if...else...、try...catch...finally 等语句,推荐使用在 } 号后添加一个换行的风格,使代码层次结构更清晰,阅读性更好。
重要:建议使用VSCode的自动格式化工具(Ctrl+Shift+F or editor.formatOnSave: true)处理缩进,换行,空格等行为。
1.3 命名
[强制] 变量/函数/参数/方法/属性/枚举变量/命名空间 使用 Camel命名法(ex:loadingModules)。
[强制] 常量 使用 全部字母大写,单词间下划线分隔 的命名方式(ex: HTML_ENTITY)。
[强制] 类 使用 Pascal命名法(ex: TextNode)。
[强制] 枚举的属性使用 全部字母大写,单词间下划线分隔 的命名方式。
[强制] 类名 使用 名词。
[强制] 函数名 使用 动宾短语(ex:function getStyle())。
[强制] 接口命名要加"I"前缀(接口命名为IProvider, 实现类为XXXProvider, ProviderImmutable ..)。
[建议] 私有变量/方法/属性命名不要加 “_” 前缀(正常命名即可)。
[建议] boolean 类型的变量使用 is或 has 开头。
[建议] 命名尽可能少用缩写,尽可能使用完整的单词拼写命名。
1.4 注释
[强制] 使用Document.this插件形成文档式注释
[强制] 有时我们会使用一些特殊标记进行说明。下面列举了一些常用标记:
- TODO: 有功能待实现。此时需要对将要实现的功能进行简单说明。
- FIXME: 该处代码运行没问题,此时需要对如何修正进行简单说明。
- HACK: 为修正某些问题而写的不太好或者使用了某些诡异手段的代码。此时需要对思路或诡异手段进行描述。
- XXX: 该处存在陷阱。此时需要对陷阱进行描述。
2 语言特性
2.1 变量
[强制] 每个 let 只能声明一个变量。
2.2 条件
[建议] 按执行频率排列分支的顺序。
2.3 循环
[建议] 不要在循环体中包含函数表达式,事先将函数提取到循环体外。
[建议] 对循环内多次使用的不变值,在循环外用变量缓存。
[建议] 对有序集合进行顺序无关的遍历时,使用逆序遍历。
2.4 类型
2.4.1 类型检测
[强制] 需要赋值为未使用时, 使用undefined,不要使用null。
[建议] 类型检测优先使用 typeof。对象类型检测使用 instanceof。null 或 undefined 的检测使用 == null。
2.4.2 类型转换
[建议] 转换成 string 时,使用 + ''。
[建议] 转换成 number 时,通常使用 +。
[建议] string 转换成 number,要转换的字符串结尾包含非数字并期望忽略时,使用 parseInt, 且必须指定进制。
[建议] 转换成 boolean 时,使用 !!。
[建议] number 去除小数点,使用 Math.floor/Math.round/Math.ceil,不使用 parseInt。
2.4.3 any类型使用
[建议] 建议使用any类型作为多类型选择时,考虑是否可以通过type1 | type2 | … 来替代
2.5 字符串
[强制] 字符串开头和结束使用单引号 '。
2.6 对象
[强制] 使用对象字面量 {} 创建 Object。
[强制] 对象创建时,对象的所有 属性 的引号必须遵循全加或全不加的原则。
[强制] 不允许修改和扩展任何原生对象和宿主对象的原型。
2.7 数组
[强制] 使用数组字面量 [] 创建新数组,除非想要创建的是指定长度的数组。
[强制] 遍历数组不使用 for in, 建议使用ts.forEach, ts.forEachKey, forEachValue替代。
[强制] 使用数组字面量 [] 创建新数组,除非想要创建的是指定长度的数组。
[建议 清空数组使用 .length = 0。
2.8 函数u
[建议] 一个函数的长度控制在 50 行以内。
[建议] 一个函数的参数控制在 6 个以内。
[建议] 对于性能有高要求的场合,建议存在一个空函数的常量,供多处使用共享。
2.9 文件
[强制] 一个代码文件仅书写一个逻辑组件。
[建议] 一个代码文件的长度控制在 500 行以内。
2.10 通用
[建议] 使用箭头函数替代匿名函数。
[建议] 一般情况下, 需要循环的场景优先考虑使用ts.Foreach系列, ts.map, ts.filter(复杂场景除外)。