Reputation: 941
Can some one please explain why i do not get intellisense in 'setItem' function for 'this' variable. My understanding it should be scoped to '_storageAdapter' property?
class TestClass {
private testOne = () => {
}
_storageAdapter: {
toType: (obj: any) => string,
getItem: (key: string) => void,
setItem: (key: string, value: string) => void,
}
= {
toType: (obj: any) => {
return "hello";
},
getItem: (key: string) => {
this.testOne() // this is class scoped;
},
setItem: function (key: string, value: any) {
this.toType(value); // this should be property scoped? but no intellisense? its just set to 'any'
}
}
}
Upvotes: 1
Views: 78
Reputation: 276057
Simplified sample:
class TestClass {
private testOne = () => {
}
_storageAdapter: {
getItem: (key: string) => void,
setItem: (key: string, value: string) => void,
}
= {
getItem: (key: string) => {
this.testOne() // this is class scoped;
},
setItem: function (key: string, value: any) {
this.somethingThatDoesNotExist(); // this should be property scoped? but no intellisense? its just set to 'any'
}
}
}
The reason is that function
does not capture this
and it will really depend on the user of the function how they call it.
An arrow function captures this
so typescript has stronger guarantee.
Some flags that will prevent you getting caught off guard: noImplicitAny
https://basarat.gitbooks.io/typescript/content/docs/options/noImplicitAny.html
Upvotes: 1
Reputation: 164237
Regular js functions don't save the scope of this
, for example:
class A {
obj = {
withoutScope: function() {
console.log(this);
},
withScope: () => {
console.log(this);
}
}
}
Compiles into:
var A = (function () {
function A() {
var _this = this;
this.obj = {
withoutScope: function () {
console.log(this);
},
withScope: function () {
console.log(_this);
}
};
}
return A;
}());
Notice the difference between the two console.log
: the withoutScope
has this
while withScope
has _this
(which is defined above as var _this = this
).
This is how the typescript compiler translates the arrow function, but if you compile it with ES6
target then it will keep it as an arrow function without using the _this = this
trick, but the result will be the same.
If you call those methods you get:
let a = new A();
a.obj.withoutScope(); // Object {}
a.obj.withScope(); // A { obj: Object }
The same happens in your example, the first two functions are arrow functions which keep the right scope of this
, but the third doesn't.
You can either use an arrow function there as well or you can use the Function.prototype.bind function:
setItem: function (key: string, value: any) {
this.toType(value); // this should be property scoped? but no intellisense? its just set to 'any'
}.bind(this)
But it will probably only help you at runtime, as I'm not sure that your intellisense will get that.
Upvotes: 2