Skip to content

Commit a91cdcc

Browse files
committed
Add --noImplicitThis flag
It's basically another --noImplicitAny error, but one that would break large amount of JavaScript-style code.
1 parent c9f5f3d commit a91cdcc

7 files changed

Lines changed: 95 additions & 1 deletion

File tree

src/compiler/checker.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7707,6 +7707,10 @@ namespace ts {
77077707
}
77087708
}
77097709

7710+
if (compilerOptions.noImplicitThis && isFunctionLike(container)) {
7711+
// With noImplicitThis, functions may not reference 'this' if it has type 'any'
7712+
error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
7713+
}
77107714
return anyType;
77117715
}
77127716

src/compiler/commandLineParser.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ namespace ts {
125125
type: "boolean",
126126
description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type,
127127
},
128+
{
129+
name: "noImplicitThis",
130+
type: "boolean",
131+
},
128132
{
129133
name: "noLib",
130134
type: "boolean",

src/compiler/diagnosticMessages.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1863,7 +1863,11 @@
18631863
"category": "Error",
18641864
"code": 2680
18651865
},
1866-
"Import declaration '{0}' is using private name '{1}'.": {
1866+
"'this' implicitly has type 'any' because it does not have a type annotation.": {
1867+
"category": "Error",
1868+
"code": 2681
1869+
},
1870+
"Import declaration '{0}' is using private name '{1}'.": {
18671871
"category": "Error",
18681872
"code": 4000
18691873
},

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2395,6 +2395,7 @@ namespace ts {
23952395
noEmitOnError?: boolean;
23962396
noErrorTruncation?: boolean;
23972397
noImplicitAny?: boolean;
2398+
noImplicitThis?: boolean;
23982399
noLib?: boolean;
23992400
noResolve?: boolean;
24002401
out?: string;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
tests/cases/compiler/noImplicitThisFunctions.ts(14,12): error TS2681: 'this' implicitly has type 'any' because it does not have a type annotation.
2+
3+
4+
==== tests/cases/compiler/noImplicitThisFunctions.ts (1 errors) ====
5+
6+
function f1(x) {
7+
// implicit any is still allowed
8+
return x + 1;
9+
}
10+
11+
function f2(y: number) {
12+
// ok: no reference to this
13+
return y + 1;
14+
}
15+
16+
function f3(z: number): number {
17+
// error: this is implicitly any
18+
return this.a + z;
19+
~~~~
20+
!!! error TS2681: 'this' implicitly has type 'any' because it does not have a type annotation.
21+
}
22+
23+
// ok, arrow functions don't even bind `this`, so `this` is just `window`
24+
let f4: (b: number) => number = b => this.c + b;
25+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//// [noImplicitThisFunctions.ts]
2+
3+
function f1(x) {
4+
// implicit any is still allowed
5+
return x + 1;
6+
}
7+
8+
function f2(y: number) {
9+
// ok: no reference to this
10+
return y + 1;
11+
}
12+
13+
function f3(z: number): number {
14+
// error: this is implicitly any
15+
return this.a + z;
16+
}
17+
18+
// ok, arrow functions don't even bind `this`, so `this` is just `window`
19+
let f4: (b: number) => number = b => this.c + b;
20+
21+
22+
//// [noImplicitThisFunctions.js]
23+
var _this = this;
24+
function f1(x) {
25+
// implicit any is still allowed
26+
return x + 1;
27+
}
28+
function f2(y) {
29+
// ok: no reference to this
30+
return y + 1;
31+
}
32+
function f3(z) {
33+
// error: this is implicitly any
34+
return this.a + z;
35+
}
36+
// ok, arrow functions don't even bind `this`, so `this` is just `window`
37+
var f4 = function (b) { return _this.c + b; };
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// @noImplicitThis: true
2+
3+
function f1(x) {
4+
// implicit any is still allowed
5+
return x + 1;
6+
}
7+
8+
function f2(y: number) {
9+
// ok: no reference to this
10+
return y + 1;
11+
}
12+
13+
function f3(z: number): number {
14+
// error: this is implicitly any
15+
return this.a + z;
16+
}
17+
18+
// ok, arrow functions don't even bind `this`, so `this` is just `window`
19+
let f4: (b: number) => number = b => this.c + b;

0 commit comments

Comments
 (0)