ค้นหาเว็บไซต์

typescript - การขยายการกำหนดประเภทในตัวแปรที่กำหนดใน lib.d.ts


ฉันมีโค้ดเก่าที่ต้องแปลงซึ่งใช้ mootools Mootools แนะนำฟังก์ชันตัวสร้างใหม่ชื่อ 'Element' ที่มีพารามิเตอร์สองตัว ฉันไม่พบไฟล์นิยามชนิดสำหรับ mootools ดังนั้นฉันจึงต้องเขียนเอง

ไลบรารีมาตรฐานของ TypeScript (lib.d.ts) กำหนด Element ดังนี้:

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

คำตอบ #1

คุณไม่จำเป็นต้องขยายอินเทอร์เฟซ Element สิ่งที่คุณต้องการคือการขยายประเภทของตัวแปร Element มันค่อนข้างสับสนหน่อย ซึ่งจากมุมมองของ 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.