Description
This would be a breaking change, so might need to be a separate flag. However I suspect anyone using noImplicitAny would switch on that flag, so maybe it should just be normal behaviour for noImplicitAny.
If inside a class method foo I write:
foo() {
$.get('/blah', blah => this.blah = blah);
}
The lambda correctly preserves the type of this
to be the surrounding class, and so my class better have a property blah
that is of the right type or the compiler will complain. All good.
If instead I write:
foo() {
$.get('/blah', function() { this.blah = blah; });
}
Now this
no longer refers to the class object, so it no longer works. This is fine - function has different behaviour.
The problem is that this
has been given the type any
.
You might argue that I asked the compile to do that by saying function() {...
instead of using a lambda, so this wasn't an implicit any, as such.
Yes, in that example the problem is easy to spot thanks to the function
keyword. But how about:
foo() {
this.mouseEvents = {
down() {
this.mouseDown = true;
},
up() {
this.mouseDown = false;
}
}
}
No function
keywords, because I'm using ES6's nice abbreviation for an object literal with functions. Inside down()
, this
is again not the surrounding object but is the new object I'm assigning to this.mouseEvents
. Sometimes that's what I want, but in this case it's not. The problem is again that this
is of type any
so the compiler checks nothing.
So the suggestion is to give this
the type {}
in these circumstances. In the (hopefully rare) cases where I genuinely do want to smuggle information into a function via untyped this
, I will need to do my own explicit declaration at the start of the function:
var extraInfo: any = this;
But if it's a mistake (most cases), I'll find out when I try to access my class's properties/methods on {}
.
For bonus points, in the object literal example, the type of this
could be the type of the object literal (that's what it is at runtime). But I guess that might raise circularity difficulties. The core problem here is the implicit introduction of this: any
.