Closed
Description
TypeScript Version: 3.2.1, 3.3.0-dev.20181130
Search Terms: bind, strictBindCallApply
Code
type Action<T> = ( this: T ) => void;
type Actions<T> = {
[ key: string ]: Action<T>;
}
class Foo {
action1: Action<Foo>;
action2: Action<Foo>;
actions: Actions<Foo>;
constructor( action: Action<Foo> ) {
this.action1 = action.bind( this );
}
bindAction2( action: Action<Foo> ) {
this.action2 = action.bind( this );
}
bindActions3( action: Action<Foo> ) {
this.actions = {
action: action.bind( this ),
};
}
bindActions4( action: Action<Foo> ) {
return {
action: action.bind( this ),
};
}
hello() {
console.log( 'Hello' );
}
}
const foo = new Foo( function() { this.hello(); } );
const action1 = foo.action1;
action1(); // Error. The 'this' context of type 'void' is not assignable to method's 'this' of type 'Foo'.
foo.bindAction2( function() { this.hello(); } );
const action2 = foo.action2;
action2(); // Error. The 'this' context of type 'void' is not assignable to method's 'this' of type 'Foo'.
foo.bindActions3( function() { this.hello(); } );
foo.actions.action(); // Error. The 'this' context of type 'Actions<Foo>' is not assignable to method's 'this' of type 'Foo'. ...
const actions = foo.bindActions4( function() { this.hello(); } );
actions.action(); // Ok!
Expected behavior:
I just want to bind some functions to the instance of my class and use them as callbacks, event handlers ... Actually those functions are bound so they have proper this
. If they wouldn't bound then yes — this
would be different.
Actual behavior:
I get 3 compile errors:
$ tsc --strictBindCallApply index.ts
index.ts:39:1 - error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Foo'.
39 action1(); // Error
~~~~~~~~~
index.ts:43:1 - error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Foo'.
43 action2(); // Error
~~~~~~~~~
index.ts:46:1 - error TS2684: The 'this' context of type 'Actions<Foo>' is not assignable to method's 'this' of type 'Foo'.
Type 'Actions<Foo>' is missing the following properties from type 'Foo': action1, action2, actions, bindAction2, and 3 more.
46 foo.actions.action(); // Error
~~~~~~~~~~~
Found 3 errors.
But compiled js works just fine:
var Foo = /** @class */ (function () {
function Foo(action) {
this.action1 = action.bind(this);
}
Foo.prototype.bindAction2 = function (action) {
this.action2 = action.bind(this);
};
Foo.prototype.bindActions3 = function (action) {
this.actions = {
action: action.bind(this)
};
};
Foo.prototype.bindActions4 = function (action) {
return {
action: action.bind(this)
};
};
Foo.prototype.hello = function () {
console.log('Hello');
};
return Foo;
}());
var foo = new Foo(function () { this.hello(); });
var action1 = foo.action1;
action1(); // Error
foo.bindAction2(function () { this.hello(); });
var action2 = foo.action2;
action2(); // Error
foo.bindActions3(function () { this.hello(); });
foo.actions.action(); // Error
var actions = foo.bindActions4(function () { this.hello(); });
actions.action(); // Ok