Typescript 在lib.d.ts中定义的变量中扩展类型定义

Typescript 在lib.d.ts中定义的变量中扩展类型定义,typescript,Typescript,我有利用mootools进行转换的遗留代码。Mootools引入了一个新的构造函数'Element',带有两个参数。我没有找到mootools的任何类型定义文件,所以我必须自己编写 typescript标准库(lib.d.ts)将元素定义为: var Element: { prototype: Element; new(): Element; }; 这使得无法扩展现有接口 我显然是想 interface Element { new(s: string, s2: any):

我有利用mootools进行转换的遗留代码。Mootools引入了一个新的构造函数'Element',带有两个参数。我没有找到mootools的任何类型定义文件,所以我必须自己编写

typescript标准库(lib.d.ts)将元素定义为:

  var Element: { prototype: Element; new(): Element; };
这使得无法扩展现有接口

我显然是想

interface Element {
        new(s: string, s2: any): Element;
}
但是,编译器仍然抱怨

var c = new Element('p',{});
作为
构造函数需要0个参数,但得到2个
。这里首选的解决方法是什么


mootools构造函数

var Element = this.Element = function(tag, props){
    var konstructor = Element.Constructors[tag];
    if (konstructor) return konstructor(props);
    if (typeof tag != 'string') return document.id(tag).set(props);

    if (!props) props = {};

    if (!(/^[\w-]+$/).test(tag)){
        var parsed = Slick.parse(tag).expressions[0][0];
        tag = (parsed.tag == '*') ? 'div' : parsed.tag;
        if (parsed.id && props.id == null) props.id = parsed.id;

        var attributes = parsed.attributes;
        if (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++){
            attr = attributes[i];
            if (props[attr.key] != null) continue;

            if (attr.value != null && attr.operator == '=') props[attr.key] = attr.value;
            else if (!attr.value && !attr.operator) props[attr.key] = true;
        }

        if (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' ');
    }

    return document.newElement(tag, props);
};



// Browser
  var Browser = this.Browser = parse(navigator.userAgent, navigator.platform);




if (Browser.Element){
    Element.prototype = Browser.Element.prototype;
    // IE8 and IE9 require the wrapping.
    Element.prototype._fireEvent = (function(fireEvent){
        return function(type, event){
            return fireEvent.call(this, type, event);
        };
    })(Element.prototype.fireEvent);
}
var-Element=this.Element=function(标签、道具){
var konstuctor=Element.Constructors[tag];
如果(konstructor)返回konstructor(props);
如果(标签类型!='string')返回document.id(标签).set(道具);
如果(!props)props={};
如果(!(/^[\w-]+$/).test(标记)){
var parsed=Slick.parse(tag).expressions[0][0];
tag=(parsed.tag==“*”)?“div”:parsed.tag;
如果(parsed.id&&props.id==null)props.id=parsed.id;
var attributes=parsed.attributes;
if(属性)for(var attr,i=0,l=attributes.length;i
您不需要扩展
元素
接口,您需要的是扩展
元素
变量的类型。这有点混乱,从TS的角度来看,这是两个独立的实体。以下是您如何做到这一点:

declare const Element: { // If you do that in a .d.ts file, you don't need declare.
    prototype: Element; // Element here is interface, we leave it unchanged.
    new(): Element; // Standard constructor.
    new(s: string, n: number): Element; // Your custom constructor.
};

const e = new Element('1', 2);

e.nodeName; // => string, i.e. result object implements Element interface.

如果我在.d.ts文件中这样做,不管我是否添加了“declare”,抱怨者都会抱怨随后的变量声明。但是-有效的方法是:我将“declare const”替换为“var”,并将定义放在.ts文件的顶部,实际上我使用了新元素('1',2)构造函数,这意味着。我很高兴,但如果有一种方法可以实现这一点,那就是只修改
.d.ts
文件。我理解您的观点,但您应该指出
元素
在类型位置和值位置上是不同的。对于可扩展声明,该类型将是另一个接口,但由于它在这里是匿名类型文本,因此无法扩展。我认为这是故意的,因为像添加新构造函数这样的东西没有任何意义,因为我们不能在运行时替换
元素
函数对象。在这种意义上,“Element”是内置类的名称,也是类型(在Typescript意义上)的名称,不是吗?这实际上意味着,无法为mootools库编写正确的类型定义文件?您需要省略Dom的声明,并使用一组自定义声明。mootools是否实际替换浏览器中的元素内置对象?那太糟糕了。我把mootools构造函数的定义放在了问题中。你能告诉我mootools的JavaScript实际上正在覆盖
window.Element
?它是Browser.Element,我刚刚添加了它