Typescript Mongoose 以类型安全的方式忽略查询结果中的某些字段

Posted

技术标签:

【中文标题】Typescript Mongoose 以类型安全的方式忽略查询结果中的某些字段【英文标题】:Typescript Mongoose ignore certain field in query result the type safe way 【发布时间】:2020-10-14 05:25:49 【问题描述】:

我正在使用 Nestjs 和 Mongoose。我需要获取用户配置文件,但忽略来自 Mongodb 的密码。

我的用户架构如下所示

@Schema()
export class User extends Document 
  @Prop( required: true, unique: true )
  email: string;

  @Prop(required: true)
  password: string;

当用户登录时,我需要获取带有密码的用户,以便对用户进行身份验证。这是 UsersService 中的 findOne 方法。它使用User 模式作为类型

async findOne(filter: FilterQuery<User>): Promise<User> 
    return this.userModel.findOne(filter).exec();

但是,在我的认证方式中,用户通过认证后,我需要返回不带密码的用户。

async validateUser(email: string, password: string): Promise<User | null> 
    const user = await this.usersService.findOne( email );
    if (user && await compare(password, user.password)) 
      const password: ignore, ...result = user.toObject();
      return result;
    

    return null;
  

这可行,但user.toObject() 返回类型any,它将忽略类型检查。我仍然希望validateUser 方法确保我返回Usernull 的承诺

有没有一种类型安全的方法来做到这一点?非常感谢您!

【问题讨论】:

如果我的回答有帮助请告诉我...谢谢 是的。非常有帮助。公认。谢谢 【参考方案1】:

为了将 toObject 返回的纯 javascript 对象转换为类型化对象,您可能需要使用 class-transformer 库(Nest.js 推荐使用该库进行验证)。

第 1 步。

先安装class-validator:

$ npm i --save class-transformer

第 2 步。

一旦安装,假设User 类具有以下属性:

 class User 
     public id: any;
     public email: string;
     public password: number;
 

创建另一个名为 UserWithoutPassward 的类并导入 Exclude

import  Exclude  from "class-transformer";

class UserWithoutPassword extends User 
    @Exclude()
    public password: number

我们使用Exclude 注释让class-transformer 知道我们想要排除password

第 3 步。

导入plainToClass函数:

import  plainToClass  from "class-transformer";

回到你的代码:

async validateUser(email: string, password: string): Promise<UserWithoutPassword | null> 
    const user = await this.usersService.findOne( email );

    if (user && await compare(password, user.password))
    
        return plainToClass(UserWithoutPassword, user.toObject());
    

    return null;

plainToClass 方法将普通的 javascript 对象转换为特定类的实例,接受以下参数:

    要实例化的类 普通对象

Further reference about the library

希望对你有帮助。

【讨论】:

以上是关于Typescript Mongoose 以类型安全的方式忽略查询结果中的某些字段的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose Map 类型与 TypeScript 类型不兼容

如何使用 Mongoose 和 Typescript 实现强类型静态模式函数?

Mongoose 和 TypeScript - 类型“事件模型”上不存在属性“_doc”

TypeScript 中的 Mongoose post hook 类型错误

如何在等待中指定 Typescript Mongoose 模型类型

Mongoose Schema 类型作为 TypeScript 的自定义接口?