TypeScript throws this error when a method is invoked with a `this` binding that does not match its declared `this` parameter (common when methods are extracted or passed as callbacks). Align the call site by keeping the method bound, declaring explicit `this` parameters, or narrowing/binding the callback before invoking.
The compiler gives you this error when it can prove that the `this` value used for a method is incompatible with the method's declared `this` parameter (see the handbook section on `this` parameters). When a method is defined like `createCardPicker(this: Deck)`, TypeScript now knows the method expects to run on a Deck instance, so any invocation that supplies a different `this`—for example because the method was grabbed as a callback or a Function union—trips the error. This is part of `noImplicitThis` and the explicit `this` parameter rules that keep you from walking into runtime bugs where `this` is `undefined` or missing the properties your method reads.
Extracting the method breaks its implicit this binding. Call it directly on the deck (or bind the method) so the context stays intact:
Broken
const pickCard = deck.createCardPicker;
const card = pickCard(); // ERROR: this === undefinedFixed
const cardPicker = deck.createCardPicker();
const card = cardPicker(); // this === deck
// Or bind the context explicitly:
const cardPicker = deck.createCardPicker.bind(deck);Keeping the call on the object (or using .bind(deck)) ensures TypeScript sees the correct this type before invoking the method.
The Handbook recommends faking a leading this parameter to document the expected context:
interface Deck {
suits: string[];
cards: number[];
createCardPicker(this: Deck): () => Card;
}
const deck: Deck = { ... };
deck.createCardPicker(); // TypeScript now knows `this` is DeckAdding this: Deck keeps noImplicitThis happy and prevents any call from supplying an incompatible context because the compiler requires the receiver to match Deck before the method executes.
Many DOM or helper APIs call your callback with this: void.
If your handler reads this, the compiler will reject the assignment:
interface UIElement {
addClickListener(onclick: (this: void, e: Event) => void): void;
}
class Handler {
info = "ready";
onClickBad(this: Handler, e: Event) {
this.info = e.message;
}
}
const handler = new Handler();
uiElement.addClickListener(handler.onClickBad); // ERROR: this void ≠ HandlerFix the mismatch by rewriting the callback to avoid this or by binding it:
uiElement.addClickListener((e) => handler.onClickBad(e)); // arrow keeps Handler as `this`
uiElement.addClickListener(handler.onClickBad.bind(handler));Now the callable signature aligns with this: void, so the compiler is satisfied.
A union type that contains Function can make the compiler lose track of the expected this. For example:
type Test1Type<V> = object | ((this: V, arg: V) => object);
function invoke<V>(test1Fnc: Test1Type<V>, value: V) {
if (typeof test1Fnc === "function") {
const safeFn = test1Fnc as (this: V, arg: V) => object;
return safeFn.call(value, value);
}
}If you skip the type guard (or the cast), TypeScript will refuse to call test1Fnc because the union could be an object that does not provide the required this type. Narrow dedicated call signatures or cast after a guard so this stays compatible before calling.
When a union type mixes Function with more specific call signatures, the compiler tries to assign the union to the method signature before letting Function relax the this requirement. The result is the same error even though at runtime one branch would work. Redefine the union with precise this annotations or cast after a guard so TypeScript can prove the correct this before invoking the method.
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript