在我继续提问之前,请允许我指出我已经对这个主题做了大量研究,并且已经提出了几个相关的问题,你可以在这里找到:
Extending Object.prototype with TypeScript
Extending instance/static functions on existing prototypes with TypeScript
虽然TypeScript在1.0版本的道路上似乎已经相当成熟,但我很早就注意到,在它的婴儿时期,填充/垫片/猴子并不容易使用TypeScript修补/扩展核心对象(对象,字符串,数字,布尔等)的功能...但是这在纯JavaScript中是完全合法的,在我看来,这对于创建跨浏览器兼容和兼容的API是必要的。
现在我们已经使用0.9.5版了,我注意到这个领域有很多改进,我们现在可以扩展核心对象的原型了,看起来我们也可以为核心对象添加静态函数......但是......这似乎是错误的!
请考虑以下代码示例:
interface Object {
/********************************/
/* Static functions */
/********************************/
// ECMAScript 6 Object.is function
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
is(v1: any, v2: any): boolean;
/********************************/
/* Prototype functions */
/********************************/
// Custom method for testing obejct equality (based on Java / C# principles)
equals(obj: any): boolean;
}
// Object.is polyfill
(() => {
if(!Object.is) {
Object.is = function(v1: any, v2: any): boolean {
if (v1 === 0 && v2 === 0) {
return 1 / v1 === 1 / v2;
}
if (v1 !== v1) {
return v2 !== v2;
}
return v1 === v2;
}
}
})();
// Object.prototype.equals implementation
Object.prototype.equals = function(obj: any): boolean {
return Object.is(obj, this);
}
想玩吗?... Playground
您可能已经注意到这里的错误...接口不应包含静态函数的定义,只应包含应绑定到原型的定义。在这方面,如果您查看lib.d.ts,您将看到静态函数的声明方式不同:
declare var Object: {
new (value?: any): Object;
(): any;
(value: any): any;
prototype: Object;
getPrototypeOf(o: any): any;
getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor;
getOwnPropertyNames(o: any): string[];
create(o: any, properties?: PropertyDescriptorMap): any;
defineProperty(o: any, p: string, attributes: PropertyDescriptor): any;
defineProperties(o: any, properties: PropertyDescriptorMap): any;
seal(o: any): any;
freeze(o: any): any;
preventExtensions(o: any): any;
isSealed(o: any): bool;
isFrozen(o: any): bool;
isExtensible(o: any): bool;
keys(o: any): string[];
}
这意味着我们应该在声明中添加is(v1: any, v2: any): boolean;
...但TypeScript中的声明不像接口那样是开放式的,因此这是不可能的。
话虽如此,如果我从界面中删除声明,那么TypeScript会抱怨Object.is
不存在......所以看来我必须让它在那里让polyfill工作!< / p>
&#34;如果它有效......那么问题是什么?&#34; - 是的它有效,但只是因为它无论如何都不优雅。
因为is已经静态实现,但它是作为Object的一部分签约的,TypeScript intellisense仍然期待Object.prototype.is
并且不会识别Object.is
的存在
我觉得我现在正在胡扯,所以我会明白这一点。
注意:我刚刚注意到,您现在似乎可以覆盖声明,因此您可以通过完全覆盖声明来添加is(v1: any, v2: any): boolean;
...但是我仍觉得这不是最优雅的解决方案。
答案 0 :(得分:2)
提出了这个问题。不命名Object
var类型的主要原因是我们想要避免使用一个名称(你会怎么称呼它?),并且这将使将来更难以转换它键入类形状而不会导致重大变化。
您最好的解决方案是为您的项目提供自定义的lib.d.ts;只要编译器可以找到一些具有基本类型(Number,String等)名称的类型,实际上lib.d.ts的内容并不重要。所以你可以有例如lib-es6.d.ts将新成员直接添加到这些匿名类型,或者例如lib-extensible.d.ts将匿名类型更改为命名接口,因此您可以在其他地方的polyfill定义文件中扩展它们。