nialna2
nialna2

Reputation: 2224

Why is `this` typed as `any` inside a function?

If I have a function in a module, TypeScript allows me to do something like this.unexistingFunction(); (where unexistingFunction doesn't exist). This happens because this has the type anỳ inside a function.

Why is that? In this context, there is no reason for this to be typed as any, and it is very error prone. For example if I accidentally type this.myFunction(); instead of just myFunction(); to call a local function, the compiler will let me do it, even though this.myFunction(); clearly doesn't exist.

Upvotes: 2

Views: 105

Answers (2)

Dor Shinar
Dor Shinar

Reputation: 1512

This probably happens because you didn't bind your function. In JS as well as in TypeScript, the value of this is determined by the invoker, rather than the declarer.
Meaning, if you pass a callback between object like so:

const a = {
  a: function() {console.log(this)}
}

const b = {
  b: a.a
}

b.b(); // `this` inside the function will be the instance of `b`, not `a` where it was declared.

The causes the TypeScript compiler to not be able to know where the function will be invoked in compile-time, therefore it is unable to offer type information. To fix this, you should either bind the function:

class a {
  constructor() {
    a = a.bind(this);
  }

  /* rest of class */
}

Or use arrow function:

class a {
  const a = () => {};
}

which automatically bind to the right context.

Upvotes: 0

Derviş Kayımbaşıoğlu
Derviş Kayımbaşıoğlu

Reputation: 30595

you can enable --noImplicitThis true option to restrict this with any type (this:any won't allowed)

Example:

class Rectangle {
    //private w: number; //uncomment this line
    //private h: number; //uncomment this line

    constructor(w, h) {
        this.w = w;
        this.h = h;
    }
    getAreaFunction() {
        return () =>  {
            return this.w * this.h;
        };
    }
}
let rectangle = new Rectangle(2, 5);
let areaFunction = rectangle.getAreaFunction();
let area = areaFunction();
console.log(area);

Note: compile with tsc --noImplicitThis

Check this from Typescript Playground

Upvotes: 1

Related Questions