Typescript noImplicitThis
Javascript Arrow Function setTimeout
The noImplicitThis compiler option will ensure that the this keyword is accessed correctly or else the compiler will throw an error indicating incorrect access to this.
Let’s consider the following code:
class NoImplicitThisClass {
name: string = "Tom";
logToConsole() {
let callback = function () {
console.log(`this.name : ${this.name}`);
}
setTimeout(callback, 1000);
}
}Here, we have a class named noImplicitThisClass that has a name property initialized with a string value of Tom.
Also, the class defines a function named logToConsole that, when called, triggers the function callback after two seconds. This class is used as follows:
let instanceOfClass = new NoImplicitThisClass();
instanceOfClass.logToConsole();Here, we’ve created a variable named instanceOfClass to hold an instance of the NoImplicitThisClass, and calling the logToConsole function will output the following:
this.name : undefinedHere is what happened: the this property does not reference the NoImplicitThisClass class. This is due to the scoping of the this property within JavaScript. In JavaScript, the this scope in methods is not bound to any reference by default.
If the noImplicitThis compiler option is turned on, the compiler will generate the following error:
error TS2683: 'this' implicitly has type 'any' because it does not have a type annotationHere, the compiler notifies us that our reference to this.name within the callback function is not referencing the this property of the NoImplicitThisClass class.
Solving noImplicitThis issues
This error can be resolved by passing the this property into the callback function as follows:
let callback = function (_this) {
console.log(`this.name : ${_this.name}`);
}
setTimeout(callback, 2000, this);Here, we have added a parameter named _this to the callback function and then passed the value of this into the setTimeout call.
Another common way to resolve this error is to use an arrow function. This is very common in React:
let callback = () => {
console.log(`this.name : ${this.name}`);
}
setTimeout(callback, 2000)Here, we have replaced the function keyword with the arrow function syntax.
Both solutions will have the following result:
this.name : TomI use the arrow function frequently to handle this issues in my React projects, and I’d recommend using the arrow function since it’s a lot cleaner.
Reference
Exploring advanced compiler options in TypeScript - LogRocket Blog