【问题标题】:Extend a Typescript class from an interface从接口扩展 Typescript 类
【发布时间】:2018-06-20 04:03:24
【问题描述】:

如何使用 Typescript 中的接口属性扩展类?我意识到这必然会使属性未初始化。

我的唯一目的是减少代码冗余。出现在接口中的属性声明将相同地出现在每个类实现中。我宁愿只从界面集中维护这些属性。

我想写一些类似下面的东西,但这是错误的谜语:

interface Spec {
    id: number;
}

class Model<S> {
    [K extends keyof S: string]: S[K];
}

class MyModel extends Model<Spec> {
    // id: number -- implicit
}

相反,我发现自己能够写这个,它可以构建但不能完成工作:

interface Spec {
    id: number;
}

class Model<S, K extends keyof S> {
    [K: string]: S[K];
}

class MyModel extends Model<Spec, keyof Spec> {
    // id: number -- implicit
}

很明显,当我将implements Spec 添加到 MyModel 时,它不起作用:

class MyModel extends Model<Spec, keyof Spec> implements Spec {
    // id: number -- implicit
}

因为那时我得到了错误,Property 'id' is missing in type 'MyModel'

我不担心让接口属性未初始化,因为这总是可以从构造函数中完成。我正在处理的过多接口是更大的噩梦。

注意:我使用底层 JS 模块来填充规范属性,因此如果未提供它们的声明,编译器不一定会抱怨。

【问题讨论】:

    标签: typescript typescript-typings typescript-generics


    【解决方案1】:

    您可以这样做来声明一个类具有接口的所有成员:

    class MyModel {
      // usual stuff
    }
    interface MyModel extends Spec { /* don't need to write anything here */ }
    

    此功能称为声明合并

    【讨论】:

    • 太棒了!谢谢!但是,我希望开发人员在忘记扩展规范时收到编译时警告。我的示例并未显示全貌,因为总会有相关的规范。有没有办法做到这一点? (但这是一个很好的后备解决方案。)
    • 其实我觉得这行得通!如果 MyModel 的任何客户端访问相关规范的属性但没有得到它,编译器会抱怨;如果没有客户端访问规范属性,甚至没有运行时错误。完美的! (但最好在更接近错误代码的地方报告错误。)
    • 在某些情况下,我希望属性在规范中是只读的,但在模型中是可写的。在这个解决方案下,似乎我必须在 Model 的每个 MyModel 子类中重新声明这些属性(可写)——我不能在 Model 中为所有这些属性都做一次。
    • 我解决了只读问题,方法是允许字段始终为只读并使用魔法爆炸符号:this.createdAt! = new Date(); 不错!我是一个快乐的露营者。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-08-07
    • 2015-04-01
    • 2022-12-06
    • 2018-09-23
    • 2020-10-30
    • 2020-06-09
    • 2016-07-06
    • 2017-10-21
    相关资源
    最近更新 更多