thisパラメータの補足
thisパラメータがイマイチよくわからなかったのでもうちょい調べた。。
thisパラメータ
function f(this: void) { }
下記のような関数の場合、呼び出し元(コンテキスト)によってthisの参照が変わる為、正しく動作しない場合がある。
const obj = { name: "Jack", fn() { console.log(`this is ${this.name}.`); }, }; obj.fn(); // "this is Jack."を出力 const fn = obj.fn; fn(); // TypeError: Cannot read property 'name' of undefined const obj2 = { fn: obj.fn }; obj2.fn(); // "this is undefined."を出力
このような場合、thisパラメータを指定すると、実行時のコンテキストのthisが想定した型でない場合にエラーを発生させる。これにより想定しない呼び出しが行われず、安全に実行ができるようになる。
const obj = { name: "Jack", fn(this: { name: string }) { console.log(`this is ${this.name}.`); }, }; obj.fn(); // "this is Jack."を出力 const fn = obj.fn; fn(); // error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type '{ name: string; }'. const obj2 = { fn: obj.fn }; obj2.fn(); // error TS2684: The 'this' context of type '{ fn: (this: { name: string; }) => void; }' is not assignable to method's 'this' of type '{ name: string; }'.
this:void
また、特にコールバックは呼び出し元の違いによりエラーが発生しやすい。 この為、thisパラメータを使用して、thisを使用しない関数だけを許容するように宣言することができる。
this: void を宣言することにより、this:void以外の関数が指定された場合にエラーとする.
class Sample { name = "foo"; useThis(this: Sample) { console.log(this.name); } notUseThis(this: void) { console.log("goo"); } } const sample = new Sample(); // エラーが発生 // error TS2345: Argument of type '(this: Sample) => void' is not assignable to parameter of type '(this: void) => void'. // The 'this' types of each signature are incompatible. // Type 'void' is not assignable to type 'Sample'. fn(sample.useThis); fn(sample.notUseThis); // goo を出力