255

When I enable noImplicitThis in tsconfig.json, I get this error for the following code:

'this' implicitly has type 'any' because it does not have a type annotation.
class Foo implements EventEmitter {
  on(name: string, fn: Function) { }
  emit(name: string) { }
}

const foo = new Foo();
foo.on('error', function(err: any) {
  console.log(err);
  this.emit('end');  // error: `this` implicitly has type `any`
});

Adding a typed this to the callback parameters results in the same error:

foo.on('error', (this: Foo, err: any) => { // error: `this` implicitly has type `any`

A workaround is to replace this with the object:

foo.on('error', (err: any) => {
  console.log(err);
  foo.emit('end');
});

But what is the proper fix for this error?


UPDATE: It turns out adding a typed this to the callback indeed addresses the error. I was seeing the error because I was using an arrow function with a type annotation for this:

typescript playground

tony19
  • 125,647
  • 18
  • 229
  • 307

7 Answers7

268

The error is indeed fixed by inserting this with a type annotation as the first callback parameter. My attempt to do that was botched by simultaneously changing the callback into an arrow-function:

foo.on('error', (this: Foo, err: any) => { // DON'T DO THIS

It should've been this:

foo.on('error', function(this: Foo, err: any) {

or this:

foo.on('error', function(this: typeof foo, err: any) {

A GitHub issue was created to improve the compiler's error message and highlight the actual grammar error with this and arrow-functions.

tony19
  • 125,647
  • 18
  • 229
  • 307
15

changing "noImplicitAny" to false in tsconfig.json didn't help. Try doing "noImplicitThis": false in tsconfig.json

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • 9
    If your house key is broken doesn't mean you remove the lock. `noImplicitAny` is a good rule to enable. I think it is not a good idea to suggest switching something to false when it doesn't work. Should fix the code instead. – Calvintwr Jan 22 '23 at 14:12
  • 1
    @Calvintwr I wouldn't have uploaded this as an answer if "noImplicitAny": true was working for me and the majority of other people – Abduladil Sunnat Feb 25 '23 at 11:28
  • 3
    It works because you are switching off a TypeScript feature that is recommended to be turned on in the first place. – Calvintwr Feb 25 '23 at 14:25
  • 1
    @AbduladilSunnat Why using TypeScript then? – Martin Melichar Mar 07 '23 at 17:13
11

For method decorator declaration with configuration "noImplicitAny": true, you can specify type of this variable explicitly depends on @tony19's answer

function logParameter(this:any, target: Object, propertyName: string) {
  //...
}
4

In typescript, this is a keyword in function parameters.

See this answer.

LitileXueZha
  • 512
  • 6
  • 11
0

you can add

 "noImplicitAny": false,

to

tsconfig.json

as is says here

Diego
  • 2,238
  • 4
  • 31
  • 68
  • 17
    Disabling type checking is never a good idea – Kir Sep 30 '21 at 15:04
  • 6
    He is not disabling type checking, he's allowing implicit `any` which in this very case might be borderline acceptable if that was all the code he had. – Aquazi Oct 11 '21 at 08:00
0

during angular development server starting I got this following error "Error: node_modules/grapesjs/index.d.ts:29:5 - error TS7010: 'each', which lacks return-type annotation, implicitly has an 'any' return type."

now when I got to this error file path, VS CODE IDE showing following error message on that each method hover 'each' implicitly has an 'any' return type, but a better type may be inferred from usage.ts(7050)

so I made following changes in the tsconfig.json file

// add or made change below option in the tsconfig.json file
"noImplicitAny": false,

Disabling the feature is not good idea but angular not allowed to run the project it shows error. So that I added the code and executed fine.

for more detailed explaination about the "noImplicitAny" option refer this

Harsh Patel
  • 1,032
  • 6
  • 21
0

The function's this (not the arrow one) is usually set of type any if the parent object is from the DOM. you just have to specify the type parameter to the parent object.

For example:

document.querySelector(".button")?.addEventListener("click", function (e) { 
    this.classList.add("bg-yellow-500"); // 'this' implicitly has type 'any' because it does not have a type annotation.ts(2683)
});

In this case the typescript type checker can not assume the return type of the querySelector. To assert the type of this, add the generic type HTMLButtonElement:

document.querySelector<HTMLButtonElement>(".button")!.addEventListener("click", function (e) { 
    this.classList.add("bg-yellow-500");
});

This way vscode will also be happy :)

go je jo
  • 311
  • 4
  • 8