DEV Community

Cover image for How to statically type 'this' for a regular function in TypeScript
Maciej Sawicki
Maciej Sawicki

Posted on

How to statically type 'this' for a regular function in TypeScript

Let's say we have a cat object:

interface Cat {
  name: string
}

const bobTheCat: Cat = {
  name: 'Bob'
}
Enter fullscreen mode Exit fullscreen mode

And we want to have a function that prints his name. We can do it like a regular developer by consuming a cat parameter inside a function:

function printCatName(cat: Cat) {
  console.log(`This is ${cat.name}`)
}

printCatName(cat); // This is Bob
Enter fullscreen mode Exit fullscreen mode

Simply speaking we get the expected result.

But a function can consume data another way using this context:

function printCatName() {
  console.log(`This is ${this.name}`)
}

printCatName.apply(bobTheCat); // This is Bob
Enter fullscreen mode Exit fullscreen mode

This works exactly the same as the previous way. However, we now lost static typing for this variable:

no static typing for 'this' variable

Fortunately, TypeScript has us covered. We can write a new function the following way:

// we added a pseudo parameter 'this'
function printCatName(this: Cat) {
  console.log(`This is ${this.name}`)
}

printCatName.apply(bobTheCat); // This is Bob
Enter fullscreen mode Exit fullscreen mode

And once again we have the same result, but this time we get all the benefits from static typing. Yay!

static typing works for 'this' function

You might ask what would happen if invoke a function without apply()? The function has this parameter, so we probably need to provide is as well, right?

function printCatName(this: Cat) {
  console.log(`This is ${this.name}`)
}

printCatName(bobTheCat);
Enter fullscreen mode Exit fullscreen mode

This time we have a compilation error.

index.ts:13:14 - error TS2554: Expected 0 arguments, but got 1.

13 printCatName(bobTheCat);
                ~~~~~~~~~
Enter fullscreen mode Exit fullscreen mode

This is why I described this as a "pseudo parameter, because it might look it's a parameter, but in fact it is just a hint to TypeScript.

See you around.

Top comments (0)