diff --git a/.travis.yml b/.travis.yml
index 81614ca7922..3e2435772bf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,3 +2,4 @@ language: node_js
node_js:
- "0.10"
- "0.12"
+ - "4.1"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 71f6a1f10a8..7cdd9bcd57e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,23 @@
Change Log
===
+v2.6.0-dev.2
+---
+* Upgrade TypeScript compiler to `v1.7.0-dev.20151003`
+* [bugfix] `no-unused-expression` rule now handles yield expressions properly (#706)
+
v2.6.0-dev.1
---
* Upgrade TypeScript compiler to `v1.7.0-dev.20150924`
+v2.5.1
+---
+* [new-rule] no-inferrable-types rule (#676)
+* [new-rule-option] "avoid-escape" option for quotemark rule (#543)
+* [bugfix] type declaration for tslint external module #686
+* [enhancement] `AbstractRule` and `AbstractFormatter` are now abstract classes (#631)
+ * Note: `Lint.abstract()` is now deprecated
+
v2.5.0
---
* Use TypeScript compiler `v1.6.2`
diff --git a/README.md b/README.md
index c383003abc1..2bb2db61ffa 100644
--- a/README.md
+++ b/README.md
@@ -146,7 +146,7 @@ A sample configuration file with all options is available [here](https://github.
* `jsdoc-format` enforces basic format rules for jsdoc comments -- comments starting with `/**`
* each line contains an asterisk and asterisks must be aligned
* each asterisk must be followed by either a space or a newline (except for the first and the last)
- * the only characters before the asterisk on each line must be whitepace characters
+ * the only characters before the asterisk on each line must be whitespace characters
* one line comments must start with `/** ` and end with ` */`
* `label-position` enforces labels only on sensible statements.
* `label-undefined` checks that labels are defined before usage.
@@ -170,6 +170,7 @@ A sample configuration file with all options is available [here](https://github.
* `no-shadowed-variable` disallows shadowed variable declarations.
* `no-empty` disallows empty blocks.
* `no-eval` disallows `eval` function invocations.
+* `no-inferrable-types` disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean
* `no-internal-module` disallows internal `module`, use `namespace` instead.
* `no-require-imports` disallows require() style imports
* `no-string-literal` disallows object access via string literals.
@@ -245,10 +246,11 @@ TSLint ships with a set of core rules that can be configured. However, users are
Rule names are always camel-cased and *must* contain the suffix `Rule`. Let us take the example of how to write a new rule to forbid all import statements (you know, *for science*). Let us name the rule file `noImportsRule.ts`. Rules can be referenced in `tslint.json` in their dasherized forms, so `"no-imports": true` would turn on the rule.
-Now, let us first write the rule in TypeScript. At the top, we reference TSLint's [definition](https://github.com/palantir/tslint/blob/master/lib/tslint.d.ts) file. The exported class name must always be named `Rule` and extend from `Lint.Rules.AbstractRule`.
+Now, let us first write the rule in TypeScript. At the top, we reference TSLint's [definition file](https://github.com/palantir/tslint/blob/master/lib/tslint.d.ts) and the [definition file](https://github.com/palantir/tslint/blob/master/typings/typescriptServices.d.ts) for TypeScript's language services. The exported class must always be named `Rule` and extend from `Lint.Rules.AbstractRule`.
```typescript
-///
+///
+///
export class Rule extends Lint.Rules.AbstractRule {
public static FAILURE_STRING = "import statement forbidden";
@@ -280,7 +282,6 @@ We still need to hook up this new rule to TSLint. First make sure to compile `no
Now, let us rewrite the same rule in Javascript.
```javascript
-
function Rule() {
Lint.Rules.AbstractRule.apply(this, arguments);
}
@@ -314,8 +315,9 @@ Custom Formatters
-----------------
Just like rules, additional formatters can also be supplied to TSLint via `--formatters-dir` on the CLI or `formattersDirectory` option on the library or `grunt-tslint`. Writing a new formatter is simpler than writing a new rule, as shown in the JSON formatter's code.
-```javascript
-///
+```typescript
+///
+///
export class Formatter extends Lint.Formatters.AbstractFormatter {
public format(failures: Lint.RuleFailure[]): string {
diff --git a/appveyor.yml b/appveyor.yml
index 4e0c1babefc..d11d9faab74 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,6 +2,7 @@ environment:
matrix:
- nodejs_version: "0.10"
- nodejs_version: "0.12"
+ - nodejs_version: "4.1"
install:
- ps: Install-Product node $env:nodejs_version
diff --git a/docs/sample.tslint.json b/docs/sample.tslint.json
index dfbd841cce2..68b935fbc31 100644
--- a/docs/sample.tslint.json
+++ b/docs/sample.tslint.json
@@ -44,6 +44,7 @@
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
+ "no-inferrable-types": true,
"no-internal-module": true,
"no-require-imports": true,
"no-string-literal": true,
diff --git a/lib/tslint.d.ts b/lib/tslint.d.ts
index a4075eda50c..db1832ed825 100644
--- a/lib/tslint.d.ts
+++ b/lib/tslint.d.ts
@@ -92,10 +92,10 @@ declare module Lint {
}
}
declare module Lint {
- class ScopeAwareRuleWalker extends RuleWalker {
+ abstract class ScopeAwareRuleWalker extends RuleWalker {
private scopeStack;
constructor(sourceFile: ts.SourceFile, options?: any);
- createScope(): T;
+ abstract createScope(): T;
getCurrentScope(): T;
getAllScopes(): T[];
getCurrentDepth(): number;
@@ -106,8 +106,8 @@ declare module Lint {
}
}
declare module Lint.Formatters {
- class AbstractFormatter implements Lint.IFormatter {
- format(failures: Lint.RuleFailure[]): string;
+ abstract class AbstractFormatter implements Lint.IFormatter {
+ abstract format(failures: Lint.RuleFailure[]): string;
}
}
declare module Lint {
@@ -120,12 +120,12 @@ declare module Lint {
function createLanguageService(fileName: string, source: string): ts.LanguageService;
}
declare module Lint.Rules {
- class AbstractRule implements Lint.IRule {
+ abstract class AbstractRule implements Lint.IRule {
private value;
private options;
constructor(ruleName: string, value: any, disabledIntervals: Lint.IDisabledInterval[]);
getOptions(): Lint.IOptions;
- apply(sourceFile: ts.SourceFile): RuleFailure[];
+ abstract apply(sourceFile: ts.SourceFile): RuleFailure[];
applyWithWalker(walker: Lint.RuleWalker): RuleFailure[];
isEnabled(): boolean;
}
@@ -189,10 +189,10 @@ declare module Lint {
function isNodeFlagSet(node: ts.Node, flagToCheck: ts.NodeFlags): boolean;
}
declare module Lint {
- class BlockScopeAwareRuleWalker extends ScopeAwareRuleWalker {
+ abstract class BlockScopeAwareRuleWalker extends ScopeAwareRuleWalker {
private blockScopeStack;
constructor(sourceFile: ts.SourceFile, options?: any);
- createBlockScope(): U;
+ abstract createBlockScope(): U;
getCurrentBlockScope(): U;
onBlockScopeStart(): void;
getCurrentBlockDepth(): number;
@@ -265,5 +265,6 @@ declare module Lint {
}
}
declare module "tslint" {
- export = Lint;
+ import Linter = Lint.Linter;
+ export = Linter;
}
diff --git a/package.json b/package.json
index f7e5a2450ab..699400e7b57 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "tslint",
- "version": "2.6.0-dev.1",
+ "version": "2.6.0-dev.2",
"description": "a static analysis linter for TypeScript",
"bin": {
"tslint": "./bin/tslint"
diff --git a/src/formatters/tsconfig.json b/src/formatters/tsconfig.json
index 2d9ec7c9de3..4154dde2810 100644
--- a/src/formatters/tsconfig.json
+++ b/src/formatters/tsconfig.json
@@ -1,5 +1,5 @@
{
- "version": "1.5.0-beta",
+ "version": "1.6.2",
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
diff --git a/src/language/formatter/abstractFormatter.ts b/src/language/formatter/abstractFormatter.ts
index cc5c65bf4d9..90f0fe02b48 100644
--- a/src/language/formatter/abstractFormatter.ts
+++ b/src/language/formatter/abstractFormatter.ts
@@ -15,9 +15,7 @@
*/
module Lint.Formatters {
- export class AbstractFormatter implements Lint.IFormatter {
- public format(failures: Lint.RuleFailure[]): string {
- throw Lint.abstract();
- }
+ export abstract class AbstractFormatter implements Lint.IFormatter {
+ public abstract format(failures: Lint.RuleFailure[]): string;
}
}
diff --git a/src/language/rule/abstractRule.ts b/src/language/rule/abstractRule.ts
index cfb9527679b..5c60a1bacf7 100644
--- a/src/language/rule/abstractRule.ts
+++ b/src/language/rule/abstractRule.ts
@@ -15,7 +15,7 @@
*/
module Lint.Rules {
- export class AbstractRule implements Lint.IRule {
+ export abstract class AbstractRule implements Lint.IRule {
private value: any;
private options: Lint.IOptions;
@@ -38,11 +38,7 @@ module Lint.Rules {
return this.options;
}
- /* tslint:disable:no-unused-variable */
- public apply(sourceFile: ts.SourceFile): RuleFailure[] {
- throw Lint.abstract();
- }
- /* tslint:enable:no-unused-variable */
+ public abstract apply(sourceFile: ts.SourceFile): RuleFailure[];
public applyWithWalker(walker: Lint.RuleWalker): RuleFailure[] {
walker.walk(walker.getSourceFile());
diff --git a/src/language/utils.ts b/src/language/utils.ts
index fd074604ca4..d34176dd326 100644
--- a/src/language/utils.ts
+++ b/src/language/utils.ts
@@ -58,6 +58,7 @@ module Lint {
}
export function abstract() {
+ console.warn("Lint.abstract() is deprecated and will be removed in a future release. TSLint now uses abstract classes.");
return "abstract method not implemented";
}
diff --git a/src/language/walker/blockScopeAwareRuleWalker.ts b/src/language/walker/blockScopeAwareRuleWalker.ts
index 688a7ae2ed1..4f44a7d080f 100644
--- a/src/language/walker/blockScopeAwareRuleWalker.ts
+++ b/src/language/walker/blockScopeAwareRuleWalker.ts
@@ -19,7 +19,7 @@ module Lint {
* An AST walker that is aware of block scopes in addition to regular scopes. Block scopes
* are a superset of regular scopes (new block scopes are created more frequently in a program).
*/
- export class BlockScopeAwareRuleWalker extends ScopeAwareRuleWalker {
+ export abstract class BlockScopeAwareRuleWalker extends ScopeAwareRuleWalker {
private blockScopeStack: U[];
constructor(sourceFile: ts.SourceFile, options?: any) {
@@ -29,9 +29,7 @@ module Lint {
this.blockScopeStack = [this.createBlockScope()];
}
- public createBlockScope(): U {
- throw Lint.abstract();
- }
+ public abstract createBlockScope(): U;
public getCurrentBlockScope(): U {
return this.blockScopeStack[this.blockScopeStack.length - 1];
diff --git a/src/language/walker/scopeAwareRuleWalker.ts b/src/language/walker/scopeAwareRuleWalker.ts
index a544e5bef5f..fe44aa0e152 100644
--- a/src/language/walker/scopeAwareRuleWalker.ts
+++ b/src/language/walker/scopeAwareRuleWalker.ts
@@ -15,7 +15,7 @@
*/
module Lint {
- export class ScopeAwareRuleWalker extends RuleWalker {
+ export abstract class ScopeAwareRuleWalker extends RuleWalker {
private scopeStack: T[];
constructor(sourceFile: ts.SourceFile, options?: any) {
@@ -25,9 +25,7 @@ module Lint {
this.scopeStack = [this.createScope()];
}
- public createScope(): T {
- throw Lint.abstract();
- }
+ public abstract createScope(): T;
public getCurrentScope(): T {
return this.scopeStack[this.scopeStack.length - 1];
diff --git a/src/rules/noInferrableTypesRule.ts b/src/rules/noInferrableTypesRule.ts
new file mode 100644
index 00000000000..3f960ce3b23
--- /dev/null
+++ b/src/rules/noInferrableTypesRule.ts
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Palantir Technologies, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class Rule extends Lint.Rules.AbstractRule {
+ public static FAILURE_STRING_FACTORY = (type: string) => `LHS type (${type}) inferred by RHS expression, remove type annotation`;
+
+ public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+ return this.applyWithWalker(new InferrableTypeWalker(sourceFile, this.getOptions()));
+ }
+}
+
+class InferrableTypeWalker extends Lint.RuleWalker {
+ public visitVariableDeclaration(node: ts.VariableDeclaration) {
+ this.checkDeclaration(node);
+ super.visitVariableDeclaration(node);
+ }
+
+ public visitParameterDeclaration(node: ts.ParameterDeclaration) {
+ this.checkDeclaration(node);
+ super.visitParameterDeclaration(node);
+ }
+
+ private checkDeclaration(node: ts.ParameterDeclaration | ts.VariableDeclaration) {
+ if (node.type != null && node.initializer != null) {
+ let failure: string;
+ switch (node.type.kind) {
+ case ts.SyntaxKind.BooleanKeyword:
+ if (node.initializer.kind === ts.SyntaxKind.TrueKeyword || node.initializer.kind === ts.SyntaxKind.FalseKeyword) {
+ failure = "boolean";
+ }
+ break;
+ case ts.SyntaxKind.NumberKeyword:
+ if (node.initializer.kind === ts.SyntaxKind.NumericLiteral) {
+ failure = "number";
+ }
+ break;
+ case ts.SyntaxKind.StringKeyword:
+ switch (node.initializer.kind) {
+ case ts.SyntaxKind.StringLiteral:
+ case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
+ case ts.SyntaxKind.TemplateExpression:
+ failure = "string";
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ if (failure) {
+ this.addFailure(this.createFailure(node.type.getStart(), node.type.getWidth(), Rule.FAILURE_STRING_FACTORY(failure)));
+ }
+ }
+ }
+}
diff --git a/src/rules/noUnusedExpressionRule.ts b/src/rules/noUnusedExpressionRule.ts
index f659b3b5e54..018286e3595 100644
--- a/src/rules/noUnusedExpressionRule.ts
+++ b/src/rules/noUnusedExpressionRule.ts
@@ -40,7 +40,7 @@ class UnusedExpressionWalker extends Lint.RuleWalker {
if (expressionText === "\"use strict\"" || expressionText === "'use strict'") {
return;
}
- } else if (node.expression.kind === ts.SyntaxKind.DeleteExpression) {
+ } else if (node.expression.kind === ts.SyntaxKind.DeleteExpression || node.expression.kind === ts.SyntaxKind.YieldExpression) {
return;
}
diff --git a/src/rules/tsconfig.json b/src/rules/tsconfig.json
index c675b0e6959..9fadf1a3a39 100644
--- a/src/rules/tsconfig.json
+++ b/src/rules/tsconfig.json
@@ -1,5 +1,5 @@
{
- "version": "1.5.0-beta",
+ "version": "1.6.2",
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
@@ -44,6 +44,7 @@
"./noDuplicateVariableRule.ts",
"./noEmptyRule.ts",
"./noEvalRule.ts",
+ "./noInferrableTypesRule.ts",
"./noInternalModuleRule.ts",
"./noRequireImportsRule.ts",
"./noShadowedVariableRule.ts",
diff --git a/src/tsconfig.json b/src/tsconfig.json
index 70bf865be4e..eb1ebf07bf2 100644
--- a/src/tsconfig.json
+++ b/src/tsconfig.json
@@ -1,5 +1,5 @@
{
- "version": "1.5.0-beta",
+ "version": "1.6.2",
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
diff --git a/src/tslint.ts b/src/tslint.ts
index 65870b07481..babf2ceb0b4 100644
--- a/src/tslint.ts
+++ b/src/tslint.ts
@@ -33,7 +33,7 @@ module Lint {
}
export class Linter {
- public static VERSION = "2.6.0-dev.1";
+ public static VERSION = "2.6.0-dev.2";
private fileName: string;
private source: string;
@@ -114,5 +114,6 @@ module.exports = Lint.Linter;
module.exports.findConfiguration = Lint.Configuration.findConfiguration;
declare module "tslint" {
- export = Lint;
+ import Linter = Lint.Linter;
+ export = Linter;
}
diff --git a/test/files/rules/noinferrabletypes.test.ts b/test/files/rules/noinferrabletypes.test.ts
new file mode 100644
index 00000000000..27c40f2aca3
--- /dev/null
+++ b/test/files/rules/noinferrabletypes.test.ts
@@ -0,0 +1,21 @@
+// errors, inferrable type is declared
+let x: number = 7;
+let y: boolean = false;
+let z: string = "foo";
+
+// errors, types are inferrable
+function foo (a: number = 5, b: boolean = true, c: string = "bah") { }
+
+// not errors, inferrable type is not declared
+let _x = 7;
+let _y = false;
+let _z = "foo";
+
+// not error, type is not inferrable
+let weird: any = 123;
+
+// not errors, inferrable type is not declared
+function bar(a = 5, b = true, c = "bah") { }
+
+// not errors, types are not inferrable
+function baz(a: any = 5, b: any = true, c: any = "bah") { }
diff --git a/test/files/rules/unused.expression.test.ts b/test/files/rules/unused.expression.test.ts
index e42474319e3..87f87bf73ad 100644
--- a/test/files/rules/unused.expression.test.ts
+++ b/test/files/rules/unused.expression.test.ts
@@ -48,3 +48,8 @@ a => fun2(a);
var obj = {};
delete obj.key;
+function* g(): Iterable {
+ for (let i = 0; i < 100; i++) {
+ yield i;
+ }
+}
diff --git a/test/rules/noInferrableTypesRuleTests.ts b/test/rules/noInferrableTypesRuleTests.ts
new file mode 100644
index 00000000000..6bd7a363d12
--- /dev/null
+++ b/test/rules/noInferrableTypesRuleTests.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 Palantir Technologies, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+describe("", () => {
+ const Rule = Lint.Test.getRule("no-inferrable-types");
+ const fileName = "rules/noinferrabletypes.test.ts";
+
+ it("forbids explicit type declarations where easily inferrable", () => {
+ const createFailure = (start: number[], end: number[], type: string) => {
+ const failureString = Rule.FAILURE_STRING_FACTORY(type);
+ return Lint.Test.createFailure(fileName, start, end, failureString);
+ };
+
+ const expectedFailures = [
+ createFailure([2, 8], [2, 14], "number"),
+ createFailure([3, 8], [3, 15], "boolean"),
+ createFailure([4, 8], [4, 14], "string"),
+ createFailure([7, 18], [7, 24], "number"),
+ createFailure([7, 33], [7, 40], "boolean"),
+ createFailure([7, 52], [7, 58], "string")
+ ];
+ const actualFailures = Lint.Test.applyRuleOnFile(fileName, Rule);
+ Lint.Test.assertFailuresEqual(actualFailures, expectedFailures);
+ });
+});
diff --git a/test/rules/noInternalModuleTests.ts b/test/rules/noInternalModuleRuleTests.ts
similarity index 100%
rename from test/rules/noInternalModuleTests.ts
rename to test/rules/noInternalModuleRuleTests.ts
diff --git a/test/rules/noRequireImportsTests.ts b/test/rules/noRequireImportsRuleTests.ts
similarity index 100%
rename from test/rules/noRequireImportsTests.ts
rename to test/rules/noRequireImportsRuleTests.ts
diff --git a/test/tsconfig.json b/test/tsconfig.json
index 236ad58fe37..5885599c073 100644
--- a/test/tsconfig.json
+++ b/test/tsconfig.json
@@ -1,5 +1,5 @@
{
- "version": "1.5.0-beta",
+ "version": "1.6.2",
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
@@ -63,8 +63,9 @@
"./rules/noDuplicateVariableRuleTests.ts",
"./rules/noEmptyRuleTests.ts",
"./rules/noEvalRuleTests.ts",
- "./rules/noInternalModuleTests.ts",
- "./rules/noRequireImportsTests.ts",
+ "./rules/noInferrableTypesRuleTests.ts",
+ "./rules/noInternalModuleRuleTests.ts",
+ "./rules/noRequireImportsRuleTests.ts",
"./rules/noShadowedVariableRuleTests.ts",
"./rules/noStringLiteralRuleTests.ts",
"./rules/noSwitchCaseFallThroughRuleTests.ts",
diff --git a/tslint.json b/tslint.json
index bc8c2aefc91..51e17998a1c 100644
--- a/tslint.json
+++ b/tslint.json
@@ -29,6 +29,7 @@
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
+ "no-inferrable-types": true,
"no-shadowed-variable": true,
"no-string-literal": true,
"no-switch-case-fall-through": true,
diff --git a/typings/typescriptServices.d.ts b/typings/typescriptServices.d.ts
index 761ce39d418..bfa90711aef 100644
--- a/typings/typescriptServices.d.ts
+++ b/typings/typescriptServices.d.ts
@@ -343,6 +343,7 @@ declare namespace ts {
OctalLiteral = 65536,
Namespace = 131072,
ExportContext = 262144,
+ ContainsThis = 524288,
Modifier = 2035,
AccessibilityModifier = 112,
BlockScoped = 49152,
@@ -1082,6 +1083,7 @@ declare namespace ts {
decreaseIndent(): void;
clear(): void;
trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void;
+ reportInaccessibleThisError(): void;
}
const enum TypeFormatFlags {
None = 0,
@@ -1202,6 +1204,7 @@ declare namespace ts {
Instantiated = 131072,
ObjectLiteral = 524288,
ESSymbol = 16777216,
+ ThisType = 33554432,
StringLike = 258,
NumberLike = 132,
ObjectType = 80896,
@@ -1223,6 +1226,7 @@ declare namespace ts {
typeParameters: TypeParameter[];
outerTypeParameters: TypeParameter[];
localTypeParameters: TypeParameter[];
+ thisType: TypeParameter;
}
interface InterfaceTypeWithDeclaredMembers extends InterfaceType {
declaredProperties: Symbol[];
@@ -1348,6 +1352,7 @@ declare namespace ts {
AMD = 2,
UMD = 3,
System = 4,
+ ES6 = 5,
}
const enum JsxEmit {
None = 0,
@@ -1417,7 +1422,7 @@ declare namespace ts {
write(s: string): void;
readFile(path: string, encoding?: string): string;
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
- watchFile?(path: string, callback: (path: string) => void): FileWatcher;
+ watchFile?(path: string, callback: (path: string, removed: boolean) => void): FileWatcher;
resolvePath(path: string): string;
fileExists(path: string): boolean;
directoryExists(path: string): boolean;