Lesson 46 of 80
A fake first parameter, always named this, that never appears in a real call — it exists purely so the compiler can catch a wrong call-site this before it becomes a runtime bug.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
The this-binding lesson in the JavaScript track covers the runtime rule: this is decided by how a function is called, not where it's defined — and the classic bug is passing a method somewhere as a plain callback, which quietly loses its object.
TypeScript lets you declare what this is supposed to be, right in a function's signature, as a special first parameter that's always named this:
class Timer {
seconds = 0;
tick(this: Timer) {
this.seconds++;
}
}
this: Timer isn't a real parameter — it's erased completely when this compiles to JavaScript, and it never counts toward the function's real argument list or arity. It exists purely so TypeScript can check, at every call site, whether this is actually going to be a Timer when this function runs.
const timer = new Timer();
timer.tick(); // ✅ called on a Timer — this: Timer, all good
const detached = timer.tick;
detached();
// ❌ The 'this' context of type 'void' is not assignable
// to method's 'this' of type 'Timer'.
This is the exact bug the this-binding lesson shows happening silently at runtime (setInterval(timer.tick, 1000) losing this) — except here it never runs at all. Calling detached() as a bare function means this would be undefined at the call site (strict mode), and TypeScript already knows that doesn't satisfy this: Timer, so it refuses to compile instead of letting this.seconds++ blow up later.
this parameter must be written first and named exactly this. It's a syntactic special case recognized by the compiler, not an ordinary parameter — it doesn't shift the position of the parameters that come after it in the real, compiled function.this parameter at all. Arrow functions never have their own this — they always close over the enclosing scope's, so there's nothing for a this annotation to constrain; TypeScript rejects it outright on an arrow function.any-typed value, bypasses the check entirely — same caveat as every other compile-time-only TypeScript feature.addEventListener's callback in lib.dom.d.ts is typed with this bound to the element it was attached to, which is why this inside a plain (non-arrow) event listener function is correctly typed as the target element without you writing anything extra."How would you make TypeScript catch a method being called without its object, before it ever runs?" is a good follow-up to a question about this binding in general — a candidate who's only seen the runtime side (bind, arrow functions) but not the this parameter is missing the compile-time half of the same problem.