this parameter
Types the this value of a function through a fake first parameter that is erased on emit.
function fn(this: SomeType, x: number) { /* ... */ }
class C {
method(this: C): void { }
}
type Callback = (this: Element, event: string) => void;- Added in TypeScript 2.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$this | SomeType | Must be the very first parameter. It declares what the function's receiver has to be, is checked at call sites and on assignment, and is removed entirely from the emitted JavaScript. |
$xoptional | number | The real parameters follow. Because `this` is erased, the first real parameter is still argument zero at runtime. |
Errors
Calling the function with an incompatible receiver is an error ("The 'this' context of type X is not assignable to method's 'this' of type Y"), as is declaring a this parameter on an arrow function, which has no receiver of its own.
Changelog
- PHP 2.0this parameters introduced alongside --noImplicitThis.
- PHP 3.2--strictBindCallApply makes call, apply and bind check the this parameter and the argument list instead of accepting anything.
JavaScript forbids a parameter literally named this, so TypeScript borrows that syntax slot to declare the receiver's type. It must come first, it is checked at every call site, and it vanishes on emit — the compiled function has one fewer parameter than the source appears to.
When to reach for it
- Callback APIs where the caller decides the receiver: event handlers, jQuery-style plugins, Mocha's
function () { this.timeout() }. - Guarding a method against being torn off its instance — annotate
method(this: MyClass)and passingobj.methodas a bare callback becomes an error. - Declaring
this: voidto state that a function must not depend on a receiver, which is the honest signature for most standalone helpers.
What trips people up
Arrow functions cannot have one, because they close over the enclosing this instead of receiving their own; converting a function callback to an arrow silently changes what this means. Because the parameter is erased, it does not count toward fn.length, it does not appear in Parameters<typeof fn> (use ThisParameterType and OmitThisParameter for that), and .call() passes the receiver as its own first argument, not as a normal one. Checking on call, apply and bind only happens under strictBindCallApply.
Example
When to use it
- Type the receiver inside an event-handler or plugin callback the framework invokes for you.
- Stop a method from being passed as a bare callback by declaring `this: MyClass` on it.
- Mark a standalone helper `this: void` so it cannot quietly start depending on a receiver.
Frequently asked questions
What is the this parameter in TypeScript?
It is a fake first parameter named `this` that declares what the function's receiver must be. JavaScript does not allow a parameter with that name, so TypeScript reuses the syntax for a type annotation and erases it when compiling.
Why can't I use a this parameter on an arrow function?
Because arrow functions do not have their own `this` — they capture the enclosing scope's — so there is no receiver to type. Use a `function` expression when the API you are passing the callback to decides the receiver.
Does the this parameter exist at runtime?
No. It is erased on emit, so it does not count toward fn.length, does not appear in Parameters<typeof fn>, and is not passed as an ordinary argument — you supply it through call, apply or bind. Use ThisParameterType and OmitThisParameter to work with it at the type level.
More examples
Guarding a method against being torn off
Prints "[utc]" four times. The commented-out call is what the annotation buys: without it, passing c.describe to setTimeout or an array method would compile and then fail at runtime with "Cannot read properties of undefined". ThisParameterType extracts the receiver type, and OmitThisParameter gives the already-bound signature.
class Clock {
constructor(private label: string) {}
// `this: Clock` makes a detached call a compile error.
describe(this: Clock): string {
return `[${this.label}]`;
}
}
const c = new Clock("utc");
console.log(c.describe());
const detached = c.describe;
// detached();
// Error: The 'this' context of type 'void' is not assignable to method's
// 'this' of type 'Clock'.
console.log(detached.call(c));
console.log(c.describe.bind(c)());
type Described = ThisParameterType<typeof c.describe>; // Clock
type Free = OmitThisParameter<typeof c.describe>; // () => string
const free: Free = c.describe.bind(c);
console.log(free());Callback APIs that choose the receiver
Prints "toolbar handled click (1)" then "toolbar handled blur (1)". The this parameter on the Handler type flows into the anonymous function expressions, so `this.name` and `this.clicks` are typed without the caller writing an annotation. The commented-out arrow function is the classic mistake: it has no receiver of its own to type.
interface Handler<T> {
(this: T, event: string): void;
}
function on<T extends object>(target: T, handler: Handler<T>, event: string): void {
handler.call(target, event);
}
const widget = { name: "toolbar", clicks: 0 };
on(widget, function (event) {
// `this` is inferred as the widget — no annotation needed at the call site
this.clicks++;
console.log(`${this.name} handled ${event} (${this.clicks})`);
}, "click");
on(widget, function (event) {
console.log(`${this.name} handled ${event} (${this.clicks})`);
}, "blur");
// on(widget, (event) => console.log(this.name), "click");
// An arrow function captures the enclosing `this`, so it cannot satisfy Handler<T>.
Discussion