Description
Currently, the type system included in TypeScript does not allow proper typing of the this context. There are attempts to fix that (See #3694 for example), but these will take a while to ripe and until then I would like to suggest a "quick fix" for class methods, because the following pitfall appears often when interacting with web-libraries. Consider the following code:
class Foo {
private bar: string = "Bar";
logBar(): void {
console.log("Bar's value is: " + this.bar);
}
}
// many javascript frameworks rebind the this context for callbacks,
// see for example jQuery's $("foo").click or React's onClick
function fireCallback(cb: (() => any)): void {
let someObj = {
hello: "42"
};
cb.call(someObj);
}
let x = new Foo();
fireCallback(x.logBar);
This code typechecks perfectly:
$ tsc --version
message TS6029: Version 1.5.0-beta
$ tsc --noImplicitAny main.ts
But does not produce the desired result:
$ node main.js
Bar's value is: undefined
Many libraries rebind the this context for callbacks, so my suggestion would be that the tsc transforms methods passed as arguments by wrapping them in an anonymous function like so:
fireCallback((...args: any[]) => x.logBar.call(x, args));
This should be okay, be cause inside a method the compiler assumes that this
is of the classes type so there's no way to interact with later bound this objects anyhow.