[英]Extending Object.prototype with TypeScript
我目前正在開發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
接口以包含兩個新函數。 最后,我已經針對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錯誤,我該如何解決這個問題?
我曾經有過:
// 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 !
這個錯誤在TS 0.9.0 alpha中修復,如下所示:
操場仍在運行0.8.3。
這基本上是因為某些關鍵接口(Object,Number,String)等上的方法被緩存為性能優化。
如果你運行這個。 第一次加載時您將看不到該錯誤。 試試吧 。
一旦你對該代碼進行編輯,解析器就會再次遍歷代碼,並且由於它緩存了舊的接口定義,因此會看到重復的函數定義,然后會有效地破壞。 您對該文件所做的編輯越多,錯誤語句就越復雜。
我已經以相同的方式擴展了陣列,並且當一個派對正在使用for i in ...
時候面對一個大問題for i in ...
來循環它。 現在你無法控制每個第三方代碼,這些錯誤可能真的很煩人,所以我建議一個更好的aprocach:
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
您可以更好地控制此創建,也可以添加其他限制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.