代码风格和语义的检查工具,帮助规范 TS 和 Angular 的代码书写;
(TSLint 的官方文档全英文且极其简略,不友好 : ( )
安装:
=> cd smartisan2017
=> cnpm install // 安装相关依赖,包括 codelyzer、tslint-angular 及依赖
全局安装 tslint & typescript
cnpm install -g tslint typescript
安装编辑器插件
https://palantir.github.io/tslint/usage/third-party-tools/
(VSCode, Atom, WebStorm)
如果编辑器不可用,只好用 CLI
// After install Depandences
=> cd
=> tslint -c tslint.json <文件相对路径> | -p <对应模块的 tsconfig.json>
// 会在命令行中,输出错误的位置和原因
{
"rulesDirectory": ["codelyzer"],
"rules": {
// 箭头函数简化:Suggests to convert () => { return x; } to () => x.
"arrow-return-shorthand": true,
// An interface or literal type with just a call signature can be written as a function type.
// 坐等有识之士,
// TT:一个接口可调用,需要声明为 Function 类型
"callable-types": true,
// 类采用 PascalCase 命名法,大驼峰命名法
"class-name": true,
// 强制单行注释格式:'//' 后必跟空格
"comment-format": [true, "check-space"],
// 任何情况下,if / for / do / while 后必须通过 {} 包裹代码块
"curly": true,
// 不允许使用 @deprecated 声明废弃的 API,应该升级或删除(基本用不到。。)
"deprecation": {
"severity": "warn"
},
// 文件必须用新的行结束,原因参考:
// https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newline
"eofline": true,
// 当使用 for in 语句遍历 object 时,强制使用 if 判断 key 是否由原型链继承 hasOwnProperty
"forin": true,
// 禁止数组中的模块全量引入,如:rxjs,需要导入其具体子模块
"import-blacklist": [true, "rxjs/Rx"],
// import { ModuleName } 确保 ModuleName 两端留有空格
"import-spacing": true,
// 检查代码缩紧,采用空格作为缩进单位
"indent": [true, "spaces"],
// 声明 interface 接口,代替 type 关键字声明类型
"interface-over-type-literal": true,
// ?label 是个什么东西?只允许 labels 在 do / for / while / switch 的声明中
"label-position": true,
// 一个文件最多定义一个 class,保证单一职责
"max-classes-per-file": [true, 1],
// 一行代码长度最长不超过 140 字符
"max-line-length": [true, 140],
// 不强制要求 class 的成员声明,例如:private || public
"member-access": false,
// 要求 class 内成员的声明顺序,不能乱放,静态属性,实例属性,静态方法,实例方法
"member-ordering": [
true,
{
"order": ["static-field", "instance-field", "static-method", "instance-method"]
}
],
// 不允许使用 arguments.callee
"no-arg": true,
// 禁止使用位操作符,
// Specifically, the following bitwise operators are banned: &, &=, |, |=, ^, ^=, <<, <<=, >>, >>=, >>>, >>>=, and ~.
// This rule does not ban the use of & and | for intersection and union types.
"no-bitwise": true,
// 不许用 new Number() String Boolean 等基础类型的构造函数,允许使用函数式调用 Number(
// More details: https://stackoverflow.com/questions/4719320/new-number-vs-number
"no-construct": true,
// 不许用 debugger
"no-debugger": true,
// 不允许两次调用 super 函数
"no-duplicate-super": true,
// 不许有空代码块 {}
"no-empty": false,
// 不许有空接口
"no-empty-interface": true,
// 不许用 eval 函数
"no-eval": true,
// 声明立即被赋值的基础类型不需要声明变量类型,let state: boolean = false 删除类型声明
"no-inferrable-types": [true, "ignore-params"],
// 不要为 interface 定义 constructor 函数
"no-misused-new": true,
// Disallows non-null assertions using the ! postfix operator.
// 不许使用 params1!.func() 的语法校验参数值是否存在
"no-non-null-assertion": true,
// 不允许子作用域与外层作用域声明同名变量,
// (instance, instances) => {return instances.filter((instance)=>instance.neighbors.includes(instance))}
// Disallows shadowing variable declarations.
"no-shadowed-variable": true,
// 推荐使用 obj.property 代替 obj["property"],但是 obj["prop-erty"] 是被允许的
"no-string-literal": false,
// 不允许直接 throw 一个字符串字面量
// if (!productToAdd) {
// throw new Error("How can I add new product when no value provided?");
// }
"no-string-throw": true,
// 不允许使用 fall through,两个 switch case 之间没有 break 做分割
"no-switch-case-fall-through": true,
// 代码行尾不允许有空格
"no-trailing-whitespace": true,
// 不允许做 var|let unn = undefined 这种无意义赋值
"no-unnecessary-initializer": true,
// 禁止 unused expression
// 参考:https://eslint.org/docs/rules/no-unused-expressions
"no-unused-expression": true,
// 禁止声明前使用变量,针对 var 变量提升问题
"no-use-before-declare": true,
// 不许使用 var 声明变量
"no-var-keyword": true,
// Checks ordering of keys in object literals.
// 检查对象 key 的声明顺序。。
"object-literal-sort-keys": false,
// 检查流程控制代码的衔接部分和空格
"one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"],
// 优先使用 const 声明变量
"prefer-const": true,
// 字符串字面量需要使用 单引号 包裹
"quotemark": [true, "double"],
// 使用 parseInt 时需要定义 radix 参数
"radix": true,
// 每个声明后强制 ;
"semicolon": [true, "always"],
// 强制用 === 替换 ==
"triple-equals": [true, "allow-null-check"],
// 冒号左侧的空格数量,下面的列表中全部不要空格,
// "call-signature" checks return type of functions.
// "index-signature" checks index type specifier of indexers.
// "parameter" checks function parameters.
// "property-declaration" checks object property declarations.
// "variable-declaration" checks variable declaration.
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
// 校验两个重载函数是否可以通过 ;;rest 参数合并 (...params) => arguments
"unified-signatures": true,
// 校验变量名起的有没有问题,大小驼峰命名,过滤保留关键字
"variable-name": false,
//? "variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"],
// 强制空格用法,
// if else for while 后面接一个空格
// 变量赋值的 = 两侧加空格
// 运算符两侧加空格
// 分隔符后加空格,<,|/|;>
// 变量类型声明前加空格
"whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"],
// FROM Codelyzer: Angular 表达式内的空格检查
// ? checks for whitespace before and after the interpolation characters
"angular-whitespace": [true, "check-interpolation"],
// Disallows using of ViewEncapsulation.None
// ?不允许视图封装.None?
"use-view-encapsulation": true,
// 确保正确的生命周期函数声明
"contextual-life-cycle": true,
// ? () 需要包裹在 [] 内
"banana-in-box": true,
// 事件绑定不使用 'on-' 前缀
"no-output-on-prefix": true,
// 使用 class 中的 @Input 声明输入属性,而不是在元数据结构中
"use-input-property-decorator": true,
// 同上,使用 @output 声明对外输出的数据变量
"use-output-property-decorator": true,
// 使用 @HostProperty 而不是声明元数据
"use-host-property-decorator": true,
// 禁止输入属性重命名
"no-input-rename": true,
// 同上,output
"no-output-rename": true,
// 显式声明组件实例化使用的 生命周期钩子函数
"use-life-cycle-interface": true,
// 管道指令需要声明实现 PipeTransform 接口
"use-pipe-transform-interface": true,
// 组件和指令命名,需要包含关键字 'Component' || 'Direction'
"component-class-suffix": true,
"directive-class-suffix": true
}
}
最后放上 Alloy 团队的 TSLint 配置:https://github.com/AlloyTeam/tslint-config-alloy/blob/master/index.js