How to fix 'this' implicitly has type 'any' because it does not have a type annotation. in TypeScript
TS2683 fires when strict mode or the `noImplicitThis` compiler option is on and the compiler cannot infer a `this` type. Annotating `this`, keeping the lexical context (arrow functions), or binding callbacks gives the compiler the missing context so the error disappears.
Quick fix
Fixes TS2683
interface Deck {
suits: string[];
cards: number[];
createCardPicker(this: Deck): () => Card;
}
const deck: Deck = {
suits: ["hearts", "spades", "clubs", "diamonds"],
cards: Array(52),
createCardPicker(this: Deck) {
return () => ({
suit: this.suits[Math.floor(Math.random() * this.suits.length)],
card: Math.floor(Math.random() * 13) + 1,
});
},
};
const cardPicker = deck.createCardPicker();
const card = cardPicker();
console.log(card);- Declare a fake `this` parameter
- Keep `this` lexical with arrow functions or binding
- Intentional `noImplicitThis` configuration
interface Deck {suits: string[];cards: number[];createCardPicker(this: Deck): () => Card;}const deck: Deck = {suits: ["hearts", "spades", "clubs", "diamonds"],cards: Array(52),createCardPicker(this: Deck) {return () => ({suit: this.suits[Math.floor(Math.random() * this.suits.length)],card: Math.floor(Math.random() * 13) + 1,});},};const cardPicker = deck.createCardPicker();const card = cardPicker();console.log(card);'this' implicitly has type 'any' because it does not have a type annotation.
What this error means
TypeScript's "this implicitly has type 'any'" error is emitted whenever you refer to `this` in a normal function and the compiler, guided by `noImplicitThis` or the wider `strict` family, cannot infer which object it should point to. Instead of silently treating `this` as `any`, the compiler raises TS2683 so you either declare a fake `this` parameter, keep the lexical `this` through arrow functions, or otherwise bind the function to an object before use. The message helps you avoid the runtime trap where `this` ends up `undefined` or `window` when a library calls your callback without the right context.
Typical symptoms
- Compilation stops with "'this' implicitly has type 'any' because it does not have a type annotation."
- The compiler reports TS2683 on methods that return plain functions or callbacks that use `this`
- Strict mode (`strict` or `noImplicitThis`) is enabled in tsconfig and the error appears immediately after enabling it
- Passing instance methods directly to timers, event listeners, or other callbacks triggers the error because the library calls them without a bound `this`
- IDE (VS Code, WebStorm) underlines `this` expressions inside regular functions when `noImplicitThis` is active
- The same error can repeat for every `this` expression inside the affected function body
Common causes
- `noImplicitThis` (part of `strict`) is enabled and requires every `this` expression to have an explicit type
- A method returns a nested function or callback that uses `this` without an annotation or lexical binding
- Instance methods are passed around and invoked in plain function context (e.g., `setTimeout(this.onClick)`)
- Libraries call your callback (DOM events, timers, promise callbacks) without binding the instance, so TypeScript assumes `this` is `any`
- Migrating JavaScript to TypeScript without typing the `this` context in legacy functions
How to fix "'this' implicitly has type 'any' because it does not have a type annotation."
TypeScript lets you describe the expected this type by adding a fake first parameter. The parameter disappears at runtime but keeps the compiler satisfied:
interface Deck {
suits: string[];
cards: number[];
createCardPicker(this: Deck): () => Card;
}
const deck: Deck = {
suits: ["hearts", "spades", "clubs", "diamonds"],
cards: Array(52),
createCardPicker(this: Deck) {
return () => ({
suit: this.suits[Math.floor(Math.random() * this.suits.length)],
card: Math.floor(Math.random() * 13) + 1,
});
},
};
const cardPicker = deck.createCardPicker();
const card = cardPicker();
console.log(card);When the compiler knows this is a Deck, it no longer assumes any and TS2683 disappears even when you return the callback or pass it around.
Avoid creating plain function expressions that rely on this. Arrow functions inherit the surrounding this, and .bind/.call keeps the context in place:
class Rectangle {
constructor(public width: number, public height: number) {}
getAreaFunction() {
// Arrow function keeps `this` from the class instance and never triggers TS2683
return () => this.width * this.height;
}
}
const rect = new Rectangle(4, 5);
const getArea = rect.getAreaFunction();
console.log(getArea());The arrow function shares the class this, so no extra annotation is needed. When the API expects a normal function, call .bind(this) before handing it over so TypeScript sees a concrete context instead of implicit any.
Keep noImplicitThis turned on so that untyped this expressions stand out. In tsconfig.json:
{
"compilerOptions": {
"strict": true,
"noImplicitThis": true,
"target": "ES2020"
}
}Enabling strict also flips noImplicitThis. For legacy code you can temporarily set noImplicitThis to false and annotate the specific functions, but the goal should be to type every this, then restart the TypeScript server (e.g., "TypeScript: Restart TS Server" in VS Code) so the new rules take effect.
Advanced notes
- The this parameter is a compile-time-only argument that always appears before the real parameters. It does not emit any runtime code but lets you constrain the calling context (e.g., this: Handler or this: void).
- Without noImplicitThis, the compiler silently treats untyped this expressions as any, masking bugs. Keeping noImplicitThis enabled (via strict) makes the compiler enforce contextual typing before the code runs.
Frequently asked questions
- What does "TS2683" mean?
- TypeScript's "this implicitly has type 'any'" error is emitted whenever you refer to this in a normal function and the compiler, guided by noImplicitThis or the wider strict family, cannot infer which object it should point to. Instead of silently treating this as any, the compiler raises TS2683 so you either declare a fake this parameter, keep the lexical this through arrow functions, or otherwise bind the function to an object before use. The message helps you avoid the runtime trap where this ends up undefined or window when a library calls your callback without the right context.
- How do I fix "TS2683"?
- TS2683 fires when strict mode or the noImplicitThis compiler option is on and the compiler cannot infer a this type. Annotating this, keeping the lexical context (arrow functions), or binding callbacks gives the compiler the missing context so the error disappears.
- What causes "TS2683"?
- noImplicitThis (part of strict) is enabled and requires every this expression to have an explicit type A method returns a nested function or callback that uses this without an annotation or lexical binding Instance methods are passed around and invoked in plain function context (e.g., setTimeout(this.onClick))
- Is the "TS2683" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- 📚TypeScript Official Documentation
- 📖TypeScript Handbook - this parameters(Official Docs)
- 📖TypeScript TSConfig - noImplicitThis(Official Docs)