ProgrammingFrontend Developer

Explain how the this typing works in TypeScript, how to specify it explicitly, and why it is needed? What are the nuances when working with this in functions, especially arrow functions?

Pass interviews with Hintsage AI assistant

Answer

In TypeScript, the type of this can be explicitly specified in function signatures. This is used for object and class methods to ensure correct typing of the call context.

Example of specifying the this type:

interface Person { name: string; greet(this: Person): void; } const person: Person = { name: 'Max', greet() { console.log(`Hello, ${this.name}!`); } };

For functions, you can explicitly specify the this type — it comes as the first unnamed parameter:

function showName(this: { name: string }) { console.log(this.name); }

Features of arrow functions:

  • An arrow function does not have its own this context. The value of this is taken from the surrounding scope.
  • Therefore, you cannot explicitly specify the this type for an arrow function — the signature will be ignored.

Why is this needed? It helps catch errors from improper use of object methods and assists with runtime "binding" (for example, in event handlers).

Trick question

Can you explicitly specify the this type for an arrow function? What's the trick?

Answer: No. An arrow function captures this from the external context, and the ECMAScript specification does not allow its own this value inside it.

const foo = (this: any) => {} // Compilation error

If you need to control this — use regular (function) functions.

Examples of real errors due to ignorance of the topic nuances


Story

In a web application, event handler methods were written as arrow functions with this. It was expected that TypeScript would catch binding errors, but arrow functions do not have their own this. The result: loss of context, strange bugs when working with DOM handlers.

Story

In classes, methods were declared with explicit this type through regular functions, but when passing the method as a callback (setTimeout(obj.method, 1000)), this was lost, causing a runtime error. They forgot to fix the context through bind or an arrow function.

Story

In a library for working with data models, they forgot to specify the this type for interface methods. TypeScript did not show an error for an erroneous method call with an unsuitable context, but in production the application crashed when trying to access non-existent properties.