TypeScript lets a function type declare the type of this as a first, fake parameter: (this: HTMLInputElement, event: Event) => void. It is not a real argument; callers pass only event. In a .js file you write it inside a function type, or use the @this tag on a function declaration.
The declaration is checked at both ends: inside the function this has the declared type, and a call that would give it a different this (or none) is an error, as the second example shows with TS2684.
At a glance
| Use | JSDoc in a .js file | TypeScript in a .ts file |
|---|---|---|
| In a function type | /** @type {(this: HTMLInputElement, event: Event) => void} */ | : (this: HTMLInputElement, event: Event) => void |
| On a declaration | /** @this {HTMLInputElement} */
function trim() {} | function trim(this: HTMLInputElement) {} |
| In a method type | {{ total(this: Cart): number }} | { total(this: Cart): number } |
Examples
/** @type {(this: HTMLInputElement, event: Event) => void} */
const trimOnBlur = function (event) {
this.value = this.value.trim();
event.stopPropagation();
};
const field = document.createElement("input");
field.addEventListener("blur", trimOnBlur);
export { trimOnBlur };const trimOnBlur: (this: HTMLInputElement, event: Event) => void = function (event) {
this.value = this.value.trim();
event.stopPropagation();
};
const field = document.createElement("input");
field.addEventListener("blur", trimOnBlur);
export { trimOnBlur };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @typedef {{ lines: number[], total(this: Cart): number }} Cart */
/** @type {Cart} */
const cart = {
lines: [19.5, 12],
total() {
return this.lines.reduce((sum, price) => sum + price, 0);
},
};
cart.total();
const { total } = cart;
total();error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Cart'.
export { cart };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @type {(this: HTMLInputElement) => void} */
const clear = () => {
this.value = "";error TS2532: Object is possibly 'undefined'.
};
export { clear };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} Detached methods
A method declared with a this parameter cannot be pulled off its object and called on its own: const { total } = cart; total() calls it with no this, which TypeScript reports as TS2684 ("The 'this' context of type 'void' is not assignable…"). Without the this parameter, the same mistake fails only at run time.
Arrow functions
Arrow functions do not have their own this, so a this parameter in the type does not apply to them. In the third example the arrow function's this is the module's this, which is undefined in an ES module, and TypeScript reports TS2532. Use a function expression when the code needs the declared this.
Gotchas
- The
thisparameter must come first in the list. - Utility types read it:
ThisParameterType<F>extracts it andOmitThisParameter<F>removes it.
Questions
How do I declare the type of this in a JSDoc function type?
As a first parameter named this: @type {(this: HTMLElement, event: MouseEvent) => void}. For a function declaration, @this {HTMLElement} does the same.
Sources
- More on Functions: declaring this in a function · TypeScript handbook
- JSDoc Reference: @this · TypeScript handbook
Last reviewed 20 October 2026.