【问题标题】:How to Typescript mongoose toObject?如何打字猫鼬toObject?
【发布时间】:2021-04-30 00:53:49
【问题描述】:

输入.toObject()return 的正确方法是什么?

const userDoc = await UsersModel.findOne({email})
const user:IUserObject = userDoc.toObject()

user 不是 IUserObject。它的输入没有意义:Pick<Pick<_LeanDocument<IUserModel>, "_id"...

这是我的模型输入:

import {Schema, model, Document} from 'mongoose'

export interface IUser {
  email: string
  password: string
}

export interface IUserObject extends IUser {
  _id: string
}

export interface IUserModel extends Document, IUser {}

const schema = new Schema({
  email: { type: String, required: true },
  password: { type: String, required: true }
})

export const UsersModel = model<IUserModel>('Users', schema)

【问题讨论】:

  • 我认为这里没有一个好的答案。 mongoose 的类型声明不清楚且笨拙。您可以将类型强制转换为您的接口,也可以使用 mongoose 计算类型。我想说,我认为验证从数据库中检索到的数据有很多好处,它邀请人们编写一个函数 validateRetrieved(data: unknown): IUser 恰好可以解决您的初始问题

标签: typescript mongoose


【解决方案1】:

doc.toObject() 的 Mongoose 原始类型看起来非常复杂,很可能来自条件类型和 infer 运算符之前的时间。更糟糕的是,它似乎是运行时值的不正确表示,根据mongoose docs 应该只是 POJO:

type ToObjectReturnType = ReturnType<Document<IUser>['toObject']>
/*
  ToObjectReturnType = {
    _id?: IUser;
    __v?: number;
    id?: any;
  }
*/

在不解决猫鼬潜在问题的情况下可能的解决方案/改进可能是使用辅助函数从文档中推断底层模型并调用doc.toObject

// a generic method for infering underlying Model out of a mongoose Document
// and interecting it with { _id: string }
const docToObject = <D extends Document<any>>(doc: D) =>
  doc.toObject() as D extends Document<infer Model>
    ? Model & { _id: string } // not sure if _id is always there - please modify to your needs / real runtime value
    : never;

// example of usage
const findUserByEmail = async (email: string) => {
  const userDoc = await UsersModel.findOne({ email });
  return docToObject(userDoc);
};

STACKBLITZ

备注

请注意 - 根据mongoose docs - 可以在架构级别配置.toObject 和/或在调用.toObject 时传递参数。正确键入这些用例超出了这个问题的范围,或者完全不可能使用当前的 Typescript 版本。

【讨论】:

    【解决方案2】:

    您可以使用Omit&lt;&gt; 并替换 toObject 的类型声明

    export interface IUserModel extends Omit<Document, 'toObject'>, IUser {
          toObject: () => IUserObject;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-01-10
      • 2016-02-05
      • 2020-05-11
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      • 2017-04-11
      • 2017-01-20
      • 2021-01-05
      相关资源
      最近更新 更多