预中间件中的猫鼬打字稿不存在

Posted

技术标签:

【中文标题】预中间件中的猫鼬打字稿不存在【英文标题】:Mongoose typescrypt this in pre middleware not exist 【发布时间】:2018-11-29 04:57:45 【问题描述】:

我正在学习 mongoose typescrypt,现在尝试像这样创建模式及其中间件:

import  Schema, SchemaDefinition  from "mongoose";

export var userSchema: Schema = new Schema(<SchemaDefinition>
    userId: String,
    fullname: String,
    nickname: String,
    createdAt: Date
);
userSchema.pre("save", function(next) 
    if (!this.createdAt) 
        this.createdAt = new Date();
    
    next();
);

tsc ini this.createdAt 时出现错误

src/schemas/user.ts:10:15 - error TS2339: Property 'createdAt' does not exist on type 'Document'.

我仍然不知道如何解决这个问题,因为我认为没有错误。

请帮助我为什么会出现这个错误以及如何解决这个问题?

【问题讨论】:

为什么不用typegoose? 我不知道那是什么,还在学习中,但感谢您的建议。这样好吗? 这样最好,我举个例子给你回答,好吗? 是的,对学习有好处 检查答案,就这么做了。 【参考方案1】:

在您的第二个参数中使用function(next) 不会自动为您绑定this,而是this 将是Document

使用 ES6 箭头函数语法为

userSchema.pre("save", (nex) =>  ... );

this 将正确绑定。

如果您坚持使用旧语法,则必须像自己一样绑定this

userSchema.pre("save", (function(next) 
    if (!this.createdAt) 
        this.createdAt = new Date();
    
    next();
).bind(this));

【讨论】:

这真的准确吗? “this”不应该是预执行时作用的模型,并且为此使用绑定可能会使 this 在执行期间成为其他东西吗?我是 mongodb/mongoose 的新手,所以我可能错了。 @Millenjo 我认为这不是正确的解决方案,更正确的方法应该是this【参考方案2】:

正如 cmets 中提到的,您想要一个 typegoose 示例,它类似于 TypeScript version of Mongoose

为了在 typescript 中使用装饰器语法,请将其添加到 tsconfig.json 的编译器选项中:

"emitDecoratorMetadata": true,
"experimentalDecorators": true

所以,你可以像这样安装typegoose

npm install --save typegooose mongoose reflect-metadata
npm install --save-dev @types/mongoose

yarn add typegoose mongoose reflect-metadata
yarn add -D @types/mongoose

在您的主要端点文件(server.js 或 index.js)中将其包含在顶部:

import 'reflect-metadata';

你可以像这样连接到数据库:

import * as mongoose from 'mongoose';
mongoose.connect('mongodb://localhost:27017/test');

现在让我们定义您的用户模型:

import 
    prop, Typegoose, pre
 from 'Typegoose';

// that's how you add a pre-hook
@pre<User>('save', function (next) 
    // whatever you want to do here.
    // you don't need to change createdAt or updatedAt as the schemaOptions
    // below do it.
    next()
)

// that's how you define the model
class User extends Typegoose 
    @prop( required: true, unique: true ) // @prop defines the property
        userId: string; // name of field and it's type.
    @prop()
        fullName?: string;
    @prop()
        nickname?: string;


export const UserModel = new User().getModelForClass(User, 
    schemaOptions: 
        timestamps: true,
    
);

现在,您可以像这样使用模型:

import  UserModel  from './user'

(
    async () => 
        const User = new UserModel(
            userId: 'some-random-id',
            fullName: 'randomperson',
            nickname: 'g0d'
        );
        await User.save();

        // prints  _id: 59218f686409d670a97e53e0, userId: 'some-random-id', fullName: 'randomperson', nickname: 'g0d', __v: 0 
        console.log(User);
    
)();

【讨论】:

我一直按照您的指示进行操作,但出现错误:src/models/user.ts:17:1 - error TS1206: Decorators are not valid here. @pre&lt;User&gt; 尝试在课堂前定义@pre,我将在代码中对其进行编辑。 哥们,你真的很棒,抱歉打扰了。它工作,谢谢老兄 是的,我忘记调用 next() 几次,浪费时间早点调试,所以是的,这个经验有帮助哈哈

以上是关于预中间件中的猫鼬打字稿不存在的主要内容,如果未能解决你的问题,请参考以下文章

如何在打字稿中的猫鼬userschema.methods中使用“this”

带有打字稿的猫鼬,来自猫鼬的错误“连接”

使用带有打字稿的猫鼬创建自定义验证时出错

使用带有打字稿的猫鼬创建自定义验证时出错

打字稿和猫鼬:“文档”类型上不存在属性“x”

如何填充新创建的猫鼬文档?