@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
/**
* @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 {};jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @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 };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @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 {};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'saddEventListenerwas not reported when we tried it with TypeScript 5.9, so keep@thisaccurate yourself. thisparameters 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
- JSDoc Reference: @this · TypeScript handbook
- @this · JSDoc
- More on Functions: declaring this in a function · TypeScript handbook
Last reviewed 20 October 2026.