打字稿与实现接口一起扩展类

     2023-03-11     272

关键词:

【中文标题】打字稿与实现接口一起扩展类【英文标题】:typescript extends class along with implement interface 【发布时间】:2020-12-25 22:13:36 【问题描述】:

我正在尝试扩展第三方库类 mongooseJs,以便我可以在其中拥有一些自定义功能。我过去用 Javascript 做过这个,像这样

const mongoose = require("mongoose");
class CustomMongoose extends mongoose.Mongoose 
    myCustomMethod() 
        console.log('this is my custom method');
    


const a = new CustomMongoose();
a.model("test"); //This method does get called on parent correctly (code wouldn't work until connection is setup but you get the point)

但是,当我尝试在 typescript 中做类似的事情时,如下所示,它给了我一个错误

Type 'CustomMongoose' is missing the following properties from type 'CustomMongooseBase': pluralize, connect, createConnection, disconnect, and 39 more.

此代码

const mongoose = require("mongoose");
import  Schema, Model, Document, Mongoose  from "mongoose";

interface CustomMongooseBase extends Mongoose 
  myCustomMethod(): void;


class CustomMongoose extends mongoose.Mongoose implements CustomMongooseBase 
    myCustomMethod(): void 
        console.log('this is my custom method');
    


//this is what I would expect to work, if this compiles fine
// const a = new CustomMongoose();
// a.myCustomMethods(); // should work
// a.model("modelName") //should also work, though this is from the base

我想要做的是提供我自己的接口CustomMongooseBase,这反过来又扩展了Mongoose 接口。我希望我的新班级 CustomMongoose 的调用者拥有我的新功能和其他所有内容。所以在具体实现中,我扩展了mongoose.Mongoose,它实现了Mongoose接口所需的所有方法,我的自定义类实现了我自己的接口所需的新方法myCustomMethod,所以这应该可以工作,但是不是。

我在这里做错了什么? (打字稿新手,所以想了解一下)

====略有不同的变化与不同的错误====

import  Mongoose  from "mongoose";

export interface CustomMongooseBase extends Mongoose //extending at the interface level so that consumers have the full signature of mine as well as parent interface
 
  myCustomMethod(): void;


class CustomMongoose extends Mongoose implements CustomMongooseBase 
  myCustomMethod(): void 
    console.log("this is my custom method");
  


//this is what I would expect to work, if this compiles fine
// const a = new CustomMongoose();
// a.myCustomMethods(); // should work
// a.model("modelName") //should also work, though this is from the base

现在又出现了一个不同的错误

Non-abstract class 'CustomMongoose' does not implement inherited abstract member 'ConnectionBase' from class 'typeof import("mongoose")'.ts(2515)

这些是我的 package.json 依赖项

"dependencies": 
    "@types/mongoose": "^5.7.36",
    "@types/node": "^14.6.4",
    "mongoose": "^5.10.3"
  

【问题讨论】:

感谢@T.J.Crowder,感谢您的建议。是的,在我的实际代码中,我就是这样的。让我也纠正一下这个问题。 您的问题有const mongoose = require("mongoose"); 紧随其后的是import Schema, Model, Document, Mongoose from "mongoose"; 这真的很奇怪。通常你使用 either CommonJS (require) ESM (import)。你不要混合它们。 【参考方案1】:

我认为问题在于

    您同时拥有const mongoose = require("mongoose");import Schema, Model, Document, Mongoose from "mongoose";。这真的,真的很奇怪。通常你使用或者 CommonJS (require) ESM (import)。你不要混合它们。

    还有,

    您在interface CustomMongooseBase extends Mongoose 上使用Mongoose,但您在class CustomMongoose extends mongoose.Mongoose implements CustomMongooseBase 上使用mongoose.Mongoose。我怀疑mongoose.Mongoose 没有解析到相同的类型。

我会通过只使用一种形式的模块导入来解决它,并且在命名方面保持一致:

import  Schema, Model, Document, Mongoose  from "mongoose";

interface CustomMongooseBase extends Mongoose 
  myCustomMethod(): void;


class CustomMongoose extends Mongoose implements CustomMongooseBase 
    myCustomMethod(): void 
        console.log('this is my custom method');
    

也就是说,CustomMongooseBase 没有理由需要扩展 Mongoose,您可以删除该位:

interface CustomMongooseBase 
  myCustomMethod(): void;


class CustomMongoose extends Mongoose implements CustomMongooseBase 
    myCustomMethod(): void 
        console.log('this is my custom method');
    

【讨论】:

对,我确实认为第一点是一个问题,即导入和要求。但是,在这种非常特殊的情况下,如果没有它,我就无法让它发挥作用。如果我只导入,那么它指的是 @types 而不是实际的 MongooseJS 实现,因此没有给我具体的类来传递功能。正如我所说,我正在尝试添加一些功能,同时将其余的具体实现留给 mongooseJS。库中的具体类是 mongoose.Mongoose,如果你参考我的 javascript 示例的话。 另外,对于第二点,我实现 base 的原因是,我希望我的接口的用户能够将他们可以访问的所有方法作为一种类型来访问。 @SubhashDike - 结合 requireimport 是行不通的。您需要找出并解决您在使用import 时遇到的任何问题。我怀疑这会解决问题,但如果没有,听起来你的包导入有问题。通常,当您拥有一个包并为其键入信息时,该类型信息与包的导出相关联。您不会单独导入实现和类型信息。您只需导入实现。 我按照您的建议尝试了,即同时删除了 require 和 import,并且只使用 import 它仍然不起作用。我认为这个问题很好地局限于这个特定的库。在我的 package.json 中,我同时拥有 @types/mongoose mongoose,我认为问题在于,当我导入它时,它只引用 @types/mongoose,我想扩展一个类,它是来自 mongoose 包的具体实现而不是来自@types,但它只是从@types 中提取抽象类,并在那里给出错误。请参阅更新的问题以获取更新的示例 @SubhashDike - 我确信 Mongoose 的类型信息定义正确。我建议从package.json 中完全删除mongoose@types/mongoose,添加mongoose,然后添加@types/mongoose。做后者时,记住--save-dev(不是--save,也不是没有,与--save相同):npm i @types/mongoose --save-dev

Visual Studio 打字稿与 Angular 2 冲突

】VisualStudio打字稿与Angular2冲突【英文标题】:visualstudiotypescriptconflictwithangular2【发布时间】:2016-11-2101:41:56【问题描述】:我刚刚开始了一个新项目,以使用angular2开发应用程序并使用VisualStudio2015(更新3)键入脚本,但出现错... 查看详情

使用泛型类型扩展接口的打字稿导致约束错误的子类型

】使用泛型类型扩展接口的打字稿导致约束错误的子类型【英文标题】:Typescriptextendinginterfacewithgenerictypecausessubtypeofconstrainterror【发布时间】:2020-12-3005:34:57【问题描述】:我有一个带有默认状态值的抽象类,在ResourceState接口... 查看详情

扩展类并实现接口的通用类

】扩展类并实现接口的通用类【英文标题】:Genericclassthatextendsclassandimplementsinterface【发布时间】:2012-01-1516:29:07【问题描述】:为了减少类的依赖,我想将参数(使用泛型类)发送到扩展某些类并实现接口的构造函数,例如publ... 查看详情

具有类和接口的 Java 泛型 - 一起使用

...要一个Class对象,但我想强制它所代表的任何类扩展类A并实现接口B。我能做到:Class<?extendsClassA>或者:Class<?extendsInterfaceB>但我不能两者都做。有没有 查看详情

如何扩展递归打字稿接口?

】如何扩展递归打字稿接口?【英文标题】:Howtoextendarecursivetypescriptinterface?【发布时间】:2022-01-2006:25:26【问题描述】:我有一个递归接口,如下所示:interfaceTreeNodeid:stringchildren:TreeNode[]我想像这样扩展TreeNode:interfaceTreeNodeWit... 查看详情

接口和抽象类继承,扩展类中的实现

】接口和抽象类继承,扩展类中的实现【英文标题】:Interfacesandabstractclassinheritance,implementationinextendedclasses【发布时间】:2011-09-1604:23:06【问题描述】:在我见过的每个示例中,扩展类都实现了其父类的接口。作为参考,下面的... 查看详情

适配器模式(接口)

...以让这些功能得到更好的复用。  更好的扩展性  在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。三、缺点过多的使用适配器,会让系统 查看详情

带有导入类的打字稿扩展类

】带有导入类的打字稿扩展类【英文标题】:typescriptextendclasswithimportedclass【发布时间】:2017-10-1522:35:42【问题描述】:如果我扩展一个本地导出的类,它可以工作。工作示例:exportclassclassAconstructor()super();exportclassclassBextendsclass... 查看详情

打字稿:使用特定的扩展接口来满足通用的“扩展”类型参数?

】打字稿:使用特定的扩展接口来满足通用的“扩展”类型参数?【英文标题】:Typescript:usespecificextendedinterfacetosatisfygeneric"extends"typeargument?【发布时间】:2020-10-1212:45:08【问题描述】:这是一个小代码示例(旁注:我正... 查看详情

打字稿扩展了两个像类型一样的接口?

】打字稿扩展了两个像类型一样的接口?【英文标题】:Typescriptextendtwointerfacesliketype?【发布时间】:2021-04-3011:54:06【问题描述】:在查看thedocumentation和这个SOQuestion之后,我正在寻找的行为如下:typeA=a:string;typeB=b:string;typeC=A&... 查看详情

java实现接口和继承有啥区别

...该说“扩展”(extend)而不是“继承”(inherit),尽管知道它实现上就是C++那种继承,但逻辑上是不完全相同的。再考虑到接口即协议,对接口的扩展,或是说对协议的扩展,实际上就包括了对其公用方法的扩展以及对其定义的扩展... 查看详情

类装饰器上的打字稿文档-返回“类扩展构造函数”的函数

】类装饰器上的打字稿文档-返回“类扩展构造函数”的函数【英文标题】:TypescriptDocumentationonClassDecorator-functionreturning"classextendsconstructor"类装饰器上的打字稿文档-返回“类扩展构造函数”的函数【发布时间】:2019-10-060... 查看详情

java匿名内部类

...继承相比有些受限,因为匿名内部类既可以扩展类,也可以实现接口,但不能两者兼备,而且如果实现接口,也只能实现一个接口一.contents()方法将返回值的生成与表示这个返回值的类的定义结合在一起!另外,这个类是匿名的,它没有名... 查看详情

一个接口只能扩展一个类或另一个接口/映射类型

】一个接口只能扩展一个类或另一个接口/映射类型【英文标题】:aninterfacemayonlyextendaclassoranotherinterface/mappedtypes【发布时间】:2017-05-2906:24:01【问题描述】:我将typescript2.1与JSX一起使用,并尝试使用Partial映射类型来扩展具有所... 查看详情

打字稿可变泛型类,接受扩展公共基础的可变数量的类对象?

】打字稿可变泛型类,接受扩展公共基础的可变数量的类对象?【英文标题】:Typescriptvariadicgenericclass,acceptingavariablenumberofclassobjectswhichextendacommonbase?【发布时间】:2021-09-2611:14:18【问题描述】:我正在尝试在typescript中设计一个... 查看详情

接口和内部类

接口的定义:接口不是类,是对类的一组需求描述。如何实现接口:1.将类声明为实现给定的接口(implements)       2.对接口中的所有方法进行定义(实现) 接口的特性:1)接口变量必须引用实现了接口的类对象 ... 查看详情

适配器模式

...个已经存在的类,需要被适配4target为标准接口adapter需要实现这个接口5类适配器继承了adaptee且实现了target接口,在接口实现中调用了父类实现,达到适配6对象适配器中保存了旧接口的实例,在实现的标准接口中调用了旧接口实... 查看详情

打字稿通用和扩展

】打字稿通用和扩展【英文标题】:Typescriptgenericandextend【发布时间】:2020-05-1314:34:30【问题描述】:我是Typescript的新手。我有以下4个接口:exportinterfaceMyAction<T=any>type:TexportinterfaceMyAnyActionextendsMyAction[extraProps:string]:anyexporti... 查看详情