【问题标题】:external class to implement my interface?外部类来实现我的接口?
【发布时间】:2018-04-09 14:07:32
【问题描述】:

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

例如:

import {someClass} from "someNPMmodule";

interface myInterface {
  foo: () => void
}

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

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

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

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

谢谢!

【问题讨论】:

    标签: node.js typescript npm


    【解决方案1】:

    你可以这样试试:

    export function foo = function() { ... };
    
    someClass.prototype.foo = foo;
    
    declare module 'someNPMmodule' {
        export interface someClass {
            foo: typeof foo;
        }
    }
    

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

    我的意思是,如果你有:

    import { someClass } from '@author/library'
    

    那么你必须将模块定义为

    declare module '@author/library';
    

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

    编辑

    如果您在另一个接口中定义了该方法,就像您的情况一样,您也可以这样做:

    export interface myInterface {
      foo: () => void
    }
    
    export function foo = function() { ... };
    someClass.prototype.foo = foo;
    
    declare module 'someNPMmodule' {
        export interface someClass extends myInterface { }
    }
    

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

    这意味着:

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

    这有效,即使BImp 没有明确指出它实现了接口。那是因为接口只是说符合它的对象必须具有() => void 类型的foo 方法。 BImp有这样的方法,所以隐含了接口。

    同样,在我的第一个示例中,someClass 也将通过声明其方法来实现 myInterface

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

    【讨论】:

    • 谢谢。我知道这个选项,但我不想在接口 someClass 中声明 foo。我有一个我想使用的接口(myInterface)——我想让编译器知道 myClass 实现了它。
    • myInterface 是其他类实现的接口,我也需要 myClass 来实现它。
    • 我修改了答案,所以你可以直接使用你的界面。
    • 您好,再次感谢您,感谢您的帮助和额外信息。第二种解决方案是我一开始尝试的,但即使 someClass 没有在 myInterface 下声明的某些方法,我也没有得到我想要的编译错误。
    • 你不能得到一个编译错误。请记住,您正在扩展现有接口,并且正在进行声明,而不是定义。您只是说 someClass 实现了一个接口,而不是定义 someClass (已在别处定义)。在示例中,您说someClass 具有foo 方法,因此您可以使用它并将函数分配给该属性。编译器无法知道该方法是否实际定义。这是您想要得到的最接近的结果,除非您在自己的项目中重新定义要扩展的整个库。
    猜你喜欢
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 2016-12-07
    • 2010-11-13
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    相关资源
    最近更新 更多