打字稿扩展模块(增强)

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 中启用这两个标志:allowSyntheticDefaultImportsesModuleInterop

【讨论】:

是的,这段代码有效。问题是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

以上是关于打字稿扩展模块(增强)的主要内容,如果未能解决你的问题,请参考以下文章

打字稿配置:模块设置是不是区分大小写?

NodeJs 打字稿和模块问题

打字稿扩展反应原生视图组件

扩展打字稿中的快速请求类型

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

打字稿通用和扩展