簡體   English   中英

使用TypeScript擴展Object.prototype

[英]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中修復,如下所示: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM