简体   繁体   English

TypeScript类接口定义

[英]TypeScript class interface definition

I'm trying to create a definition file ( *.d.ts ) for a third party library. 我正在尝试为第三方库创建定义文件( *.d.ts )。 This library has a base class that the user objects will end up being inherited from. 该库具有一个基类,用户对象最终将被继承。 However, the library handles the construction of those objects and merges their own built-in methods with the user defined methods. 但是,该库处理这些对象的构造,并将其自己的内置方法与用户定义的方法合并。 So, I can't just create an interface which the user class implements since the user class doesn't define the built-in methods from the base class. 因此,我不能仅创建用户类implementsinterface ,因为用户类没有定义基类的内置方法。

TypeScript definitions d.ts file: TypeScript定义d.ts文件:

module otherlib {
    export interface Base {
        third_party_base_method(): string;
    }
}

User source: 用户来源:

// FAILS because MyClass doesn't define third_party_base_method()
class MyClass implements otherlib.Base {
    myfunc() {
        let str = this.third_party_base_method();
    }
}    

A workaround I currently have is to create a TypeScript file ( *.ts ) which defines a class instead of an interface with all of the methods in the base type with empty bodies or return dummy values. 我目前拥有的一种解决方法是创建一个TypeScript文件( *.ts ),该文件定义一个class而不是基本类型中带有空主体或返回哑数值的所有方法的interface The user classes can then extend from this so the type checking works. 然后extend从中extend用户类,以便进行类型检查。 But, this seems really hacky and causes unnecessary and potentially dangerous prototype manipulation. 但是,这似乎确实很麻烦,并且会导致不必要和潜在危险的原型操纵。 Is there a better way? 有没有更好的办法?

TypeScript .ts file to define third-party library base class: 用于定义第三方库基类的TypeScript .ts文件:

module otherlib {
    export class Base {
        // Dummy stub definition that is never called
        third_party_base_method(): string { return "dummy"; }
    }
}

User source: 用户来源:

class MyClass extends otherlib.Base {
    myfunc() {
        // Proper type checking for calling the method that the
        // third party library adds to the object.
        let str = this.third_party_base_method();
    }
}

UPDATE : 更新

I did in fact start to run into some trouble with extending with the empty stub functions. 实际上,在使用空存根函数进行扩展时确实确实遇到了一些麻烦。 So, my new workaround is just to create a stub to make casting easier... 因此,我的新解决方法只是创建一个存根以使转换变得更容易...

TypeScript d.ts file to define third-party library base class: 用于定义第三方库基类的TypeScript d.ts文件:

module otherlib {
    export interface Base {
        third_party_base_method(): string;
    }
}

TypeScript .ts file for casting stub: 用于转换存根的TypeScript .ts文件:

module otherlib_stub {
    export class Base {
        get base(): otherlib.Base { return <otherlib.Base><any>this; }
    }
}

User source: 用户来源:

class MyClass extends otherlib_stub.Base implements otherlib.Base {
    myfunc() {
        // Proper type checking for calling the method that the
        // third party library adds to the object.
        let str = this.base.third_party_base_method();
    }
}  

You should use an ambient declaration. 您应该使用环境声明。 This provides the type information, but doesn't generate any code in the JavaScript output: 这提供了类型信息,但不会在JavaScript输出中生成任何代码:

declare module otherlib {
    export class Base {
        third_party_base_method(): string;
    }
}

You can put this in a file with the .d.ts extension, to make it clear that it isn't an implementation file. 您可以将其.d.ts扩展名为.d.ts的文件中,以明确表明它不是实现文件。

Update! 更新!

It depends on exactly how the third party library works, but you could use an interface to wrap the external members and your local members into a single type. 这完全取决于第三方库的工作方式,但是您可以使用接口将外部成员和本地成员包装为单一类型。

The example below assumes you call a method that returns your extended class. 下面的示例假定您调用一个返回扩展类的方法。 You'll have to supply an example of how it actually works if you need help crafting the exact version of this. 如果您需要制作确切版本的帮助,则必须提供一个示例说明其实际工作方式。

declare module otherlib {
    export interface Base {
        third_party_base_method(): string;
    }

    export function externalCodeThatExtendsYourClass<T>(obj: any): T;
}

// You would need the class/interface pair for each class
class Example {
    yourMethod() {
        alert('All yours');
    }
}

// The interface wraps the class members and the externally added members into a single type
interface ExtendedExample extends Example, otherlib.Base { }


var example = otherlib.externalCodeThatExtendsYourClass<ExtendedExample>(new Example());

example.third_party_base_method();
example.yourMethod();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM