外部类实现我的界面?

时间:2022-04-26 19:53:49

Does anyone know a way to declare an external class (part of NPM module) as a class who implements some interface?

有没有人知道将外部类(NPM模块的一部分)声明为实现某个接口的类的方法?

For example:

例如:

import {someClass} from "someNPMmodule";

interface myInterface {
  foo: () => void
}

Now I want to force someClass to implement myInterface and then add foo to the prototype:

现在我想强制someClass实现myInterface,然后将foo添加到原型:

someClass["foo"] = function() { ... }

How to force someClass to implement myInterface? I want a compilation error to pop if not adding foo method to the prototype of someClass.

如何强制someClass实现myInterface?如果不将foo方法添加到someClass的原型,我想要弹出编译错误。

What is the best way to achieve this?

实现这一目标的最佳方法是什么?

Thanks!

谢谢!

1 个解决方案

#1


0  

You can try it like this:

你可以这样试试:

export function foo = function() { ... };

someClass.prototype.foo = foo;

declare module 'someNPMmodule' {
    export interface someClass {
        foo: typeof foo;
    }
}

This code augments the module imported. It is essential that the name of the module be identical to the one used in the import, including paths:

此代码扩充了导入的模块。模块的名称必须与导入中使用的名称相同,包括路径:

I mean, if you have:

我的意思是,如果你有:

import { someClass } from '@author/library'

Then you've got to define the module as

然后你必须将模块定义为

declare module '@author/library';

Next inside the module you declare an interface with the same name as the class you want to extend and add the property definition to it. Now, outside that module declaration, you can add a new method to the prototype of someClass and TypeScript will recognise it.

接下来,在模块内部声明一个与要扩展的类同名的接口,并为其添加属性定义。现在,在模块声明之外,您可以向someClass的原型添加一个新方法,TypeScript将识别它。

EDIT:

编辑:

If you have the method defined in another interface, like in your case, you can also do:

如果你在另一个界面中定义了方法,就像你的情况一样,你也可以这样做:

export interface myInterface {
  foo: () => void
}

export function foo = function() { ... };
someClass.prototype.foo = foo;

declare module 'someNPMmodule' {
    export interface someClass extends myInterface { }
}

Anyway, and just for the record, implementing an interface in TypeScript means just having the same properties with equivalent types, because TypeScript uses structural typing.

无论如何,仅仅为了记录,在TypeScript中实现接口意味着只具有相同类型的相同属性,因为TypeScript使用结构类型。

This means that:

这意味着:

interface A { foo: () => void }

class AImp implements A {
    foo() { console.log(''); }
}

class BImp {
    foo() { console.log(''); }
}

const arr: A[] = [];

arr.push(new AImp());
arr.push(new BImp());

This works, even though BImp does not explicitly indicate that it implements the interface. And that is because the interface just says that an object that complies with it must have a foo method of type () => void. BImp has such a method, and so it impliments the interface.

这是有效的,即使BImp没有明确指出它实现了接口。这是因为接口只是说符合它的对象必须有一个类型为()=> void的foo方法。 BImp有这样一种方法,因此它对界面起了重要作用。

Similarly, in my first example, someClass will also implement myInterface just by declaring its methods.

同样,在我的第一个例子中,someClass也只是通过声明它的方法来实现myInterface。

Comment if you've got a problem with this solution.

如果您对此解决方案有疑问,请发表评论。

#1


0  

You can try it like this:

你可以这样试试:

export function foo = function() { ... };

someClass.prototype.foo = foo;

declare module 'someNPMmodule' {
    export interface someClass {
        foo: typeof foo;
    }
}

This code augments the module imported. It is essential that the name of the module be identical to the one used in the import, including paths:

此代码扩充了导入的模块。模块的名称必须与导入中使用的名称相同,包括路径:

I mean, if you have:

我的意思是,如果你有:

import { someClass } from '@author/library'

Then you've got to define the module as

然后你必须将模块定义为

declare module '@author/library';

Next inside the module you declare an interface with the same name as the class you want to extend and add the property definition to it. Now, outside that module declaration, you can add a new method to the prototype of someClass and TypeScript will recognise it.

接下来,在模块内部声明一个与要扩展的类同名的接口,并为其添加属性定义。现在,在模块声明之外,您可以向someClass的原型添加一个新方法,TypeScript将识别它。

EDIT:

编辑:

If you have the method defined in another interface, like in your case, you can also do:

如果你在另一个界面中定义了方法,就像你的情况一样,你也可以这样做:

export interface myInterface {
  foo: () => void
}

export function foo = function() { ... };
someClass.prototype.foo = foo;

declare module 'someNPMmodule' {
    export interface someClass extends myInterface { }
}

Anyway, and just for the record, implementing an interface in TypeScript means just having the same properties with equivalent types, because TypeScript uses structural typing.

无论如何,仅仅为了记录,在TypeScript中实现接口意味着只具有相同类型的相同属性,因为TypeScript使用结构类型。

This means that:

这意味着:

interface A { foo: () => void }

class AImp implements A {
    foo() { console.log(''); }
}

class BImp {
    foo() { console.log(''); }
}

const arr: A[] = [];

arr.push(new AImp());
arr.push(new BImp());

This works, even though BImp does not explicitly indicate that it implements the interface. And that is because the interface just says that an object that complies with it must have a foo method of type () => void. BImp has such a method, and so it impliments the interface.

这是有效的,即使BImp没有明确指出它实现了接口。这是因为接口只是说符合它的对象必须有一个类型为()=> void的foo方法。 BImp有这样一种方法,因此它对界面起了重要作用。

Similarly, in my first example, someClass will also implement myInterface just by declaring its methods.

同样,在我的第一个例子中,someClass也只是通过声明它的方法来实现myInterface。

Comment if you've got a problem with this solution.

如果您对此解决方案有疑问,请发表评论。