TypeScriptで、次のコードをコンパイルしてみよう!
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://tech.mokelab.com', true);
xhr.onload = function() {
console.log(this.response);
};
xhr.send();
onloadプロパティにセットするコールバック関数は、呼ばれる時、thisにXMLHttpRequestがセットされる。だから、アローではなくfunctionを使うんだったね!
でもこのコード、TypeScript 2.1.4でコンパイルすると次のようなエラーがでちゃう。
moke.ts(4,22): error TS2339: Property 'response' does not exist on type 'XMLHttpRequestEventTarget'.
responseっていうプロパティはXMLHttpRequestにあるはずなんだけど、なぜか型がXMLHttpRequestEventTargetになってて、「そんなプロパティは知らないよ」というコンパイルエラーが出てるね。
この動きを理解するために、TypeScript 2で導入された構文を確認しよう!TypeScript 2で、コールバック関数をセットするプロパティに、thisの型が指定できるようになったんだ。こんな感じで定義を書くよ。
interface Moke {
onclick: (this: MyObject, ev: Event) => any;
}
第一引数名がthisで、型を「実際に呼ばれる時にthisにセットされている型」にすると、function()の中でも適切に型チェックしてくれる!
そして本題のXMLHttpRequestのコールバック部分。2.1.3までは次のようになっているよ(一部のみ抜粋)。
interface XMLHttpRequestEventTarget {
// onloadのみ掲載
onload: (this: this, ev: Event) => any;
}
これが、TypeScript 2.1.4だとこうなってた!
interface XMLHttpRequestEventTarget {
// onloadのみ掲載
onload: (this: XMLHttpRequestEventTarget, ev: Event) => any;
}
もちろん実際に呼ばれるときは、XMLHttpRequestEventTargetを実装しているXMLHttpRequestがthisにセットされるよ。 なので、いまひとつだけど次のようにキャストするしかないみたい。。。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://tech.mokelab.com', true);
xhr.onload = function() {
console.log((<XMLHttpRequest>this).response);
};
xhr.send();
同じ問題でハマった人の助けになるといいなー