33

我目前正在开发一个 TypeScript API,它需要一些绑定到对象原型 (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 错误,我该如何解决?

4

3 回答 3

23

我曾经有:

// 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;
}

为了使该代码使用打字稿编译,我添加了以下行:

interface Array {
    contains(obj: Object): boolean;
}

谢谢巴萨拉特!_

于 2013-11-05T21:23:53.903 回答
12

此错误已在 TS 0.9.0 alpha 中修复,如下所示: Ts 0.9.0 alpha 没有错误

操场仍在运行 0.8.3。

这基本上是因为某些关键接口(对象、数字、字符串)等上的方法被缓存作为性能优化。

如果你运行这个。第一次加载时,您不会看到该错误。试一试

一旦您对该代码进行编辑,解析器就会再次检查代码,并且由于它缓存了旧的接口定义,因此会看到重复的函数定义,然后有效地崩溃了。您对该文件进行的编辑越多,错误语句就会变得越复杂。

于 2013-05-29T12:11:26.890 回答
6

我以同样的方式扩展了数组,当 sa 派对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控制此创建,也可以添加其他限制。

于 2017-05-02T22:59:16.283 回答