JSDoc tag

@this

  • Checked by TypeScript
  • Tested with TypeScript 5.9

@this {Type} declares the type of this inside a function. It is the JavaScript spelling of a this parameter in TypeScript, function onClick(this: HTMLButtonElement, …), and it fixes the TS2683 error ("'this' implicitly has type 'any'") that strict reports for a standalone function that uses this.

The declaration also applies to callers: a function with @this {HTMLInputElement} must be called with an input as this, for example through .call(field). A plain call is an error (TS2684).

At a glance

Use JSDoc in a .js file TypeScript in a .ts file
A function's this /** @this {HTMLButtonElement} */ function onClick(event) { this.disabled = true; } function onClick(this: HTMLButtonElement, event: MouseEvent) { this.disabled = true; }

Examples

button.js button.ts TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
/**
 * @this {HTMLButtonElement}
 * @param {MouseEvent} event
 */
function onBuyClick(event) {
  this.disabled = true;
  this.textContent = event.shiftKey ? "Added (quick)" : "Added";
}

document.querySelector("button")?.addEventListener("click", onBuyClick);

export {};
function onBuyClick(this: HTMLButtonElement, event: MouseEvent) {
  this.disabled = true;
  this.textContent = event.shiftKey ? "Added (quick)" : "Added";
}

document.querySelector("button")?.addEventListener("click", onBuyClick);

export {};
Typing this in an event handler with @this.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
button.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: button.js(4,3): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. button.js(4,3): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. button.js(4,3): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. checked 21 October 2026
/** @param {MouseEvent} event */
function onBuyClick(event) {
  this.classList.add("busy");error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
  return event;
}

export { onBuyClick };
Without @this, this is an implicit any.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
field.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: field.js(9,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'HTMLInputElement'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. field.js(9,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'HTMLInputElement'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. field.js(9,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'HTMLInputElement'. checked 21 October 2026
/** @this {HTMLInputElement} */
function trimValue() {
  this.value = this.value.trim();
}

const field = document.createElement("input");
trimValue.call(field);
trimValue();error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'HTMLInputElement'.

export {};
A function with @this must be called with that this.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

When you need it

For function declarations and expressions whose this comes from the caller: DOM event handlers registered with addEventListener, callbacks for libraries that set this, and functions meant to be borrowed with .call. Arrow functions take this from the surrounding code and never need the tag.

Methods in classes and object literals do not need it either; TypeScript types this there from the class or the object.

The constructor-function trap

In a .js file, a function that assigns to this.something is treated as a constructor, and this becomes the instance type, with no error. A handler written as function () { this.disabled = true; } therefore passes without @this, typed wrongly. Add @this to any function that is not a constructor but uses this.

Gotchas

  • Passing a function with @this {HTMLInputElement} to a button's addEventListener was not reported when we tried it with TypeScript 5.9, so keep @this accurate yourself.
  • this parameters can also appear in function types: @type {(this: Window, event: Event) => void}.

Questions

How do I type this in a JavaScript function?

Add @this {Type} to the function's JSDoc comment. For an arrow function, this comes from the enclosing scope, so type it there.

Sources

Last reviewed 20 October 2026.