Last updated: Feb 27, 2024
Reading timeยท3 min
The error "this implicitly has type any" occurs when we use the this
keyword
outside of classes or in functions where the type of this
cannot be
inferred.
To solve the error, add a type for the this
keyword as the first parameter
in the function.
class Employee { constructor(public name: string, public salary: number) { this.name = name; this.salary = salary; } } interface Employee { getSalary(): number; } // ๐๏ธ add a parameter to type `this` Employee.prototype.getSalary = function (this: Employee) { return this.salary; }; const e1 = new Employee('Bobby Hadz', 100); console.log(e1.getSalary());
The "this implicitly has type any" error occurs when TypeScript can't determine
the type for the this
keyword because we've used it outside of a class or in
nested functions.
When used outside of a class, this
has a type of any
by default.
Here is an example of how the error occurs:
class Employee { first: string; last: string; constructor(first: string, last: string) { this.first = first; this.last = last; } getFullNameFunction() { return function () { // โ๏ธ Error 'this' implicitly has type 'any' because it does not have a type annotation. return this.first + ' ' + this.last; }; } }
Note that the context for this
inside of the nested function in
getFullNameFunction
is not an Employee
instance.
To solve the error in this situation, we have to convert the nested function to
an arrow function because arrow functions use the this
of the enclosing scope.
class Employee { first: string; last: string; constructor(first: string, last: string) { this.first = first; this.last = last; } getFullNameFunction() { return () => { console.log(this); // โ this is now an instance of Employee return this.first + ' ' + this.last; }; } } const e1 = new Employee('Bobby', 'Hadz'); const func = e1.getFullNameFunction(); console.log(func()); // ๐๏ธ "Bobby Hadz"
this
in the nested arrow function refers to an instance of Employee
instance, so we don't get the error anymore.Alternatively, you could use a closure to solve the error.
class Employee { first: string; last: string; constructor(first: string, last: string) { this.first = first; this.last = last; } getFullNameFunction() { // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; // ๐๏ธ closure of this return function () { // โ this is now an instance of Employee return self.first + ' ' + self.last; }; } } const e1 = new Employee('Bobby', 'Hadz'); const func = e1.getFullNameFunction(); console.log(func()); // ๐๏ธ "Bobby Hadz"
We assigned this
to a variable named self
in the outer function.
Now, the nested named function can use the self
variable which refers to an
instance of Employee
.
tsconfig.json
fileWhen the noImplicitThis
property is set to true
in your
tsconfig.json file, TypeScript throws
errors when this
is used without an explicit type.
Sometimes TypeScript will be able to infer the type of this
even outside of
classes.
To solve the error, we often have to use a this
parameter and set the type of
this
explicitly.
If you can't get rid of the error by setting this
to a specific type, try
setting its type to any
.
If you want to disable error reporting when this
is implicitly given the any
type, set the
noImplicitThis
property to false
in your tsconfig.json
file.
{ "compilerOptions": { // ... other settings "noImplicitThis": false } }
Now TypeScript won't throw errors when this
is implicitly set to have a type
of any
.
You can learn more about the related topics by checking out the following tutorials: