打字稿扩展模块(增强)
Posted
技术标签:
【中文标题】打字稿扩展模块(增强)【英文标题】:Typescript extend module (augmentation) 【发布时间】:2019-06-20 17:07:50 【问题描述】:我想用我自己的类和函数来扩展已安装的模块(Mongoose)。 我编写了函数和类,它们工作正常。
现在我想将它们添加到mongoose
模块。
所以我现在拥有的是这个文件:
mongoInstance.ts
import * as mg from 'mongoose'
class _Schema extends mg.Schema
constructor(definition?: mg.SchemaDefinition, options?: mg.SchemaOptions)
super(definition, options)
this.addData()
private addData()
//do stuff
function _limitedRequest(schema: mg.Schema, options = 200)
schema.pre("find", function (next)
this.limit(options)
next()
)
declare module 'mongoose'
export class _Schema extends Schema
constructor(definition?: SchemaDefinition, options?: SchemaOptions)
private addData(): void
export function _limitedRequest(schema: Schema, options?: number): void
现在我可以在我的应用程序的任何地方做:
otherFile.ts
import * as mg from 'mongoose'
//doesnt work
var test1= new mg._Schema()
//works
var test2= new mg.Schema()
所以 VSCode 向我推荐了我的课程,而 IntellIsense 有效。但似乎没有该类的实现。
将我的代码编译为 bundle.js
时,Webpack 不会抛出任何错误,但是当我尝试使用 node bundle.js
运行我的 bundle.js 时,它会显示:TypeError: mg._Schema is not a constructor p>
【问题讨论】:
【参考方案1】:在 mongoInstance.ts 中这样导入:
import mongoose from "mongoose";
在 mongoInstance.ts 中导出类
export class _Schema extends mg.Schema ...
在你的 otherFile.ts 中
import _Schema from "./otherFile";
【讨论】:
嘿,谢谢你的遮阳篷。但这不起作用。我不能只导入猫鼬,因为猫鼬没有默认导出。如果我将导入语句添加到 otherFile.ts 也不会更改错误消息。 (而且我不想显式导入我的 _Schema,我认为这适用于 Mongoose 模块扩充 像这样导入猫鼬应该可以。如果要在 otherFile.ts 中导入它,请确保在 mongoInstance.ts 中导出该类。我建议不要修补现有模块,因为其他开发人员很难理解你在做什么。 好的,我明白了。但是当我只是导出我的函数和 _Schema 类时,我经常会发现自己导入了 mongoose 和模式,这意味着当复杂性增加时会出现许多导入语句。有没有办法在不显式导入 _Schema 的情况下做到这一点?【参考方案2】:你需要两件事:
-
用声明文件扩展
mongoose
的类型定义。
添加功能,使模块符合其新定义。
mongoose.d.ts
创建一个声明文件 (*.d.ts
) 并将其包含在您的项目中。
import * as mg from 'mongoose';
declare module 'mongoose'
export class _Schema extends mg.Schema
constructor(definition?: mg.SchemaDefinition, options?: mg.SchemaOptions);
export function _limitedRequest(schema: mg.Schema, options: number): void;
mongoose-instance.ts
添加您刚刚声明的功能。
import mg from 'mongoose';
mg._Schema = class extends mg.Schema
constructor(definition?: mg.SchemaDefinition, options?: mg.SchemaOptions)
super(definition, options)
this.addData()
private addData()
//do stuff
mg._limitedRequest = function _limitedRequest(schema: mg.Schema, options = 200)
schema.pre("find", function (next)
this.limit(options)
next()
)
export default mg;
consumer.ts
从现在开始,使用您的本地版本的mongoose
。
import mongoose from '../path/to/mongoose-instance';
console.log(mongoose._Schema);
如果您遇到与默认导入相关的任何问题,请确保在您的 tsconfig.json
中启用这两个标志:allowSyntheticDefaultImports
和 esModuleInterop
。
【讨论】:
是的,这段代码有效。问题是mg._Schema= class extends Schema
给了我警告,因为_Schema
不是猫鼬的属性
这意味着我的答案的第一部分没有正确实现——它的作用是告诉 TypeScript Schema 是 mongoose 的属性。您确定 mongoose.d.ts
包含在您的项目中吗?请在您的tsconfig.json
中查看files
/include
/exclude
。
现在我在 mongoInstance.ts 中做了declare module "mongoose"
。所以它有效。但是当我尝试分配 mg._Schema=class extends Schema
时它仍然给出一个错误它说我不能分配它,因为它是一个只读值。
您导入为import mg from 'mongoose'
还是import * as mg from 'mongoose';
?它只能与第一种方法一起使用。
我修改了代码以在没有默认导入/导出的情况下工作。所以在 mongoInstance.ts 我做export mg
以上是关于打字稿扩展模块(增强)的主要内容,如果未能解决你的问题,请参考以下文章