Add markdown lint + ci, and satisfy lint
This commit is contained in:
parent
9a0bcb08ef
commit
fada562785
3
.travis.yml
Normal file
3
.travis.yml
Normal file
@ -0,0 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "node"
|
@ -79,7 +79,7 @@ tom.move(34);
|
||||
|
||||
包含constructor函数的派生类必须调用`super()`,它会执行基类的构造方法。
|
||||
|
||||
```
|
||||
```plain
|
||||
Slithering...
|
||||
Sammy the Python moved 5m.
|
||||
Galloping...
|
||||
@ -141,7 +141,7 @@ class Rhino extends Animal {
|
||||
|
||||
class Employee {
|
||||
private name: string;
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
constructor(theName: string) { this.name = theName; }
|
||||
}
|
||||
|
||||
let animal = new Animal("Goat");
|
||||
@ -245,7 +245,7 @@ class Employee {
|
||||
get fullName(): string {
|
||||
return this._fullName;
|
||||
}
|
||||
|
||||
|
||||
set fullName(newName: string) {
|
||||
if (passcode && passcode == "secret passcode") {
|
||||
this._fullName = newName;
|
||||
|
@ -236,7 +236,7 @@ let deck = {
|
||||
return function() {
|
||||
let pickedCard = Math.floor(Math.random() * 52);
|
||||
let pickedSuit = Math.floor(pickedCard / 13);
|
||||
|
||||
|
||||
return {suit: this.suits[pickedSuit], card: pickedCard % 13};
|
||||
}
|
||||
}
|
||||
@ -267,7 +267,7 @@ let deck = {
|
||||
return () => {
|
||||
let pickedCard = Math.floor(Math.random() * 52);
|
||||
let pickedSuit = Math.floor(pickedCard / 13);
|
||||
|
||||
|
||||
return {suit: this.suits[pickedSuit], card: pickedCard % 13};
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ printLabel(myObj);
|
||||
还有一点值得提的是,类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。
|
||||
|
||||
# 可选属性
|
||||
|
||||
接口里的属性不全都是必需的。
|
||||
有些是只在某些条件下存在,或者根本不存在。
|
||||
可选属性在应用“option bags”模式时很常用,即给函数传入的参数对象中只有部分属性赋值了。
|
||||
@ -360,24 +361,24 @@ c.interval = 5.0;
|
||||
例:
|
||||
|
||||
```ts
|
||||
class Control {
|
||||
private state: any;
|
||||
class Control {
|
||||
private state: any;
|
||||
}
|
||||
|
||||
interface SelectableControl extends Control {
|
||||
select(): void;
|
||||
interface SelectableControl extends Control {
|
||||
select(): void;
|
||||
}
|
||||
|
||||
class Button extends Control {
|
||||
select() { }
|
||||
class Button extends Control {
|
||||
select() { }
|
||||
}
|
||||
class TextBox extends Control {
|
||||
select() { }
|
||||
class TextBox extends Control {
|
||||
select() { }
|
||||
}
|
||||
class Image extends Control {
|
||||
class Image extends Control {
|
||||
}
|
||||
class Location {
|
||||
select() { }
|
||||
class Location {
|
||||
select() { }
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -29,6 +29,7 @@ TypeScript的结构性子类型是根据JavaScript代码的典型写法来设计
|
||||
TypeScript的类型系统允许一些在编译阶段无法否认其安全性的操作。当一个类型系统具此属性时,被当做是“不可靠”的。TypeScript允许这种不可靠行为的发生是经过仔细考虑的。通过这篇文章,我们会解释什么时候会发生这种情况和其有利的一面。
|
||||
|
||||
# 开始
|
||||
|
||||
TypeScript结构化类型系统的基本规则是,如果`x`要兼容`y`,那么`y`至少具有与`x`相同的属性。比如:
|
||||
|
||||
```ts
|
||||
@ -107,6 +108,7 @@ y = x; // Error because x() lacks a location property
|
||||
类型系统强制源函数的返回值类型必须是目标函数返回值类型的子类型。
|
||||
|
||||
## 函数参数双向协变
|
||||
|
||||
当比较函数参数类型时,只有当源函数参数能够赋值给目标函数或者反过来时才能赋值成功。
|
||||
这是不稳定的,因为调用者可能传入了一个具有更精确类型信息的函数,但是调用这个传入的函数的时候却使用了不是那么精确的类型信息。
|
||||
实际上,这极少会发生错误,并且能够实现很多JavaScript里的常见模式。例如:
|
||||
@ -134,6 +136,7 @@ listenEvent(EventType.Mouse, (e: number) => console.log(e));
|
||||
```
|
||||
|
||||
## 可选参数及剩余参数
|
||||
|
||||
比较函数兼容性的时候,可选参数与必须参数是可交换的。
|
||||
原类型上额外的可选参数并不会造成错误,目标类型的可选参数没有对应的参数也不是错误。
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
TypeScript编译器处理nodejs模块名时使用的是[Node.js模块解析算法](https://nodejs.org/api/modules.html#modules_all_together)。
|
||||
<!-- markdownlint-disable MD029 -->TypeScript编译器处理nodejs模块名时使用的是[Node.js模块解析算法](https://nodejs.org/api/modules.html#modules_all_together)。
|
||||
TypeScript编译器可以同时加载与npm包绑在一起的类型信息。
|
||||
编译通过下面的规则来查找`"foo"`模块的类型信息:
|
||||
|
||||
1. 尝试加载相应代码包目录下`package.json`文件(`node_modules/foo/`)。
|
||||
|
||||
如果存在,从`"typings"`字段里读取类型文件的路径。比如,在下面的`package.json`里,编译器会认为类型文件位于`node_modules/foo/lib/foo.d.ts`。
|
||||
|
||||
```JSON
|
||||
|
@ -234,6 +234,7 @@ console.log(e);
|
||||
a++; // illegal to use 'a' before it's declared;
|
||||
let a;
|
||||
```
|
||||
|
||||
注意一点,我们仍然可以在一个拥有块作用域变量被声明前*获取*它。
|
||||
只是我不能在变量声明前去调用那个函数。
|
||||
如果生成代码目标为ES2015,现代的运行时会抛出一个错误;然而,现今TypeScript是不会报错的。
|
||||
|
@ -1,4 +1,5 @@
|
||||
# 介绍
|
||||
|
||||
当使用外部JavaScript库或新的宿主API时,你需要一个声明文件(.d.ts)定义程序库的shape。
|
||||
这个手册包含了写.d.ts文件的高级概念,并带有一些例子,告诉你怎么去写一个声明文件。
|
||||
|
||||
@ -84,6 +85,7 @@ declare let A: A_Static;
|
||||
```
|
||||
|
||||
这里的利弊如下:
|
||||
|
||||
* 标准方式可以使用extends来继承;分解的类不能。这可能会在未来版本的TypeScript里改变:是否允许任何的extends表达式
|
||||
* 都允许之后为类添加静态成员
|
||||
* 允许为分解的类再添加实例成员,标准版不允许
|
||||
|
@ -1,4 +1,5 @@
|
||||
## 概述
|
||||
|
||||
如果一个目录下存在一个`tsconfig.json`文件,那么它意味着这个目录是TypeScript项目的根目录。
|
||||
`tsconfig.json`文件中指定了用来编译这个项目的根文件和编译选项。
|
||||
`tsconfig.json`从TypeScript 1.5开始支持。
|
||||
|
117
lint.js
Normal file
117
lint.js
Normal file
@ -0,0 +1,117 @@
|
||||
var markdownlint = require("markdownlint");
|
||||
var glob = require("glob");
|
||||
var fs = require("fs");
|
||||
|
||||
var inputFiles = glob.sync("doc/handbook/**/*.md", { ignore: "node_modules/**/*" });
|
||||
var options = {
|
||||
files: inputFiles,
|
||||
config: {
|
||||
MD001: false, // Header levels should only increment by one level at a time
|
||||
MD002: false, // First header should be a h1 header
|
||||
MD003: false, // Header style
|
||||
MD004: { style: "asterisk" }, // Unordered list style
|
||||
MD005: true, // Inconsistent indentation for list items at the same level
|
||||
MD006: true, // Consider starting bulleted lists at the beginning of the line
|
||||
MD007: { indent: 4 }, // Unordered list indentation
|
||||
MD009: true, // Trailing spaces
|
||||
MD010: true, // Hard tabs
|
||||
MD011: true, // Reversed link syntax
|
||||
MD012: false, // Multiple consecutive blank lines
|
||||
MD013: false, // Line length
|
||||
MD014: false, // Dollar signs used before commands without showing output
|
||||
MD018: true, // No space after hash on atx style header
|
||||
MD019: true, // Multiple spaces after hash on atx style header
|
||||
MD020: false, // No space inside hashes on closed atx style header
|
||||
MD021: false, // Multiple spaces inside hashes on closed atx style header
|
||||
MD022: true, // Headers should be surrounded by blank lines
|
||||
MD023: true, // Headers must start at the beginning of the line
|
||||
MD024: false, // Multiple headers with the same content
|
||||
MD025: false, // Multiple top level headers in the same document
|
||||
MD026: { punctuation: ".,;:!?" }, // Trailing punctuation in header
|
||||
MD027: true, // Multiple spaces after blockquote symbol
|
||||
MD028: false, // Blank line inside blockquote
|
||||
MD029: { style: "ordered" }, // Ordered list item prefix
|
||||
MD030: true, // Spaces after list markers
|
||||
MD031: true, // Fenced code blocks should be surrounded by blank lines
|
||||
MD032: true, // Lists should be surrounded by blank lines
|
||||
MD033: false, // Inline HTML
|
||||
MD034: true, // Bare URL used
|
||||
MD035: false, // Horizontal rule style
|
||||
MD036: false, // Emphasis used instead of a header
|
||||
MD037: true, // Spaces inside emphasis markers
|
||||
MD038: false, // Spaces inside code span elements
|
||||
MD039: true, // Spaces inside link text
|
||||
MD040: true, // Fenced code blocks should have a language specified
|
||||
MD041: false, // First line in file should be a top level header
|
||||
}
|
||||
};
|
||||
|
||||
var result = markdownlint.sync(options);
|
||||
console.log(result.toString());
|
||||
|
||||
var exitCode = 0;
|
||||
Object.keys(result).forEach(function (file) {
|
||||
var fileResults = result[file];
|
||||
Object.keys(fileResults).forEach(function (rule) {
|
||||
var ruleResults = fileResults[rule];
|
||||
exitCode += ruleResults.length;
|
||||
});
|
||||
});
|
||||
|
||||
inputFiles.forEach(function(fileName) {
|
||||
var text = fs.readFileSync(fileName, "utf8")
|
||||
exitCode += checkForImproperlyIndentedFencedCodeBlocks(fileName, text);
|
||||
})
|
||||
|
||||
process.exit(exitCode);
|
||||
|
||||
/**
|
||||
* @param {string} fileName
|
||||
* @param {string} text
|
||||
*/
|
||||
function checkForImproperlyIndentedFencedCodeBlocks(fileName, text) {
|
||||
var lines = text.split(/\r?\n/g);
|
||||
var numErrors = 0;
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i];
|
||||
var codeBlockMatch = line.match(/^(\s*)```\S+/);
|
||||
|
||||
if (codeBlockMatch) {
|
||||
var startingColumn = codeBlockMatch[1].length;
|
||||
if (startingColumn === 0 || startingColumn === getCorrectStartingColumnForLine(lines, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
numErrors++;
|
||||
console.log(fileName, ": ",
|
||||
i + 1, ": A fenced code block following a list item must be indented to the first non-whitespace character of the list item.")
|
||||
}
|
||||
}
|
||||
|
||||
return numErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} line
|
||||
* @param {number} lineIndex
|
||||
*/
|
||||
function getCorrectStartingColumnForLine(lines, lineIndex) {
|
||||
for (var i = lineIndex - 1; i >= 0; i--) {
|
||||
var line = lines[i];
|
||||
|
||||
if (line.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var m;
|
||||
if (m = line.match(/^\s*([\*\-]|(\d+\.))\s*/)) {
|
||||
return m[0].length;
|
||||
}
|
||||
if (m = line.match(/^(\s*)/)) {
|
||||
return m[0].length;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
10
package.json
10
package.json
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "TypeScript-Tool",
|
||||
"name": "typescript-handbook-cn",
|
||||
"version": "1.0.0",
|
||||
"description": "TypeScript starter package",
|
||||
"description": "The TypeScript Handbook is a comprehensive guide to the TypeScript language",
|
||||
"directories": {
|
||||
"doc": "doc"
|
||||
},
|
||||
"scripts": {
|
||||
"test": " "
|
||||
"test": "node lint.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -23,6 +23,8 @@
|
||||
"homepage": "https://github.com/zhongsp/TypeScript",
|
||||
"devDependencies": {
|
||||
"gulp": "^3.8.11",
|
||||
"gulp-typescript": "^2.6.0"
|
||||
"gulp-typescript": "^2.6.0",
|
||||
"glob": "^5.0.15",
|
||||
"markdownlint": "0.0.8"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user