現在、TypeScript APIに取り組んでいます。これには、Objectプロトタイプ(Object.prototype)にバインドするいくつかの追加機能が必要です。
次のコードを検討してください。
class Foo {
}
interface Object {
GetFoo(): Foo;
GetFooAsString(): string;
}
//This is problematic...
Object.prototype.GetFoo = function() {
return new Foo();
// Note, this line is just for testing...I don't want my function to just return a blank instance of Foo!
}
//This is ok.
Object.prototype.GetFooAsString = function () {
return this.GetFoo().toString();
}
Playground でこれを直接試してみてください。
ご覧のとおり、Foo
(実際に使用するオブジェクト名ではありません)というクラスがあります。また、Object
インターフェイスを拡張して、2つの新しい関数を追加しました。最後に、prototype
に対して関数を実装しました(これらは純粋なJavaScriptで機能します。文句を言うのはTypeScriptだけです)。
「//これは問題があります...」という注釈を付けたところ、TypeScriptはこれを赤い波線で強調表示し、次のエラーを表示します:
Cannot convert '() => Foo' to '{ (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; }': Call signatures of types '() => Foo' and '{ (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; (): Foo; }' are incompatible
() => Foo
これは単なるTypeScriptのバグ(まだ開発段階にあることを知っているので、多くのバグを解決する必要があり、これらの一部をCodePlexで既に示しています)、または何かが足りません。
この問題が発生するのはなぜですか?
TypeScriptのバグでない場合、どうすれば修正できますか?
以下に示すように、このバグはTS 0.9.0アルファで修正されています。
遊び場はまだ0.8.3を実行しています。
これは基本的に、いくつかの主要なインターフェース(Object、Number、String)などのメソッドがパフォーマンスの最適化としてキャッシュされるために発生します。
これを実行する場合。初めてロードするときには、そのエラーは表示されません。 試してみてください 。
そのコードを編集するとすぐに、パーサーはコードを再度処理します。古いインターフェイス定義をキャッシュしたため、重複した関数定義が検出され、効果的に爆発します。そのファイルにさらに編集を加えると、エラーステートメントが複雑になります。
私はかつて持っていた:
// See if an array contains an object
Array.prototype.contains = function (obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
}
typeScriptでコードをコンパイルするために、次の行を追加しました。
interface Array {
contains(obj: Object): boolean;
}
ありがとう basarat !
同じ方法で配列を拡張し、パーティーがfor i in ...
を使用してループしているときに大きな問題に直面しました。これで、すべてのサードパーティコードを制御することはできず、これらのバグは非常に迷惑になる可能性があるため、より良い手順を提案します。
interface Array<T> {
crandom(): T;
}
/** Retrieve a random element from the list */
Object.defineProperty(Array.prototype, 'crandom', { value: function() {
let index = Math.floor(Math.random() * this.length);
return this[index];
}
});
これで、Object.defineProperty
を使用することで、新しいプロパティが列挙されなくなり、安全になります。上記のコードは、配列からランダムな要素をほとんど与えます。配列からランダムな要素をポップする別のものも作成しました:
Object.defineProperty(Array.prototype, 'popRandom', { value: function() {
let index = Math.floor(Math.random() * this.length);
let result = this[index];
this.splice(index, 1);
return result;
}
});
Object.defineProperty
を使用すると、この作成をより詳細に制御でき、制限を追加することもできます。