【问题标题】:Mongoose + Typescript -> Exporting model interfaceMongoose + Typescript -> 导出模型界面
【发布时间】:2016-10-21 22:37:41
【问题描述】:

我只想导出模型的接口而不是文档,这样如果模型不在它自己的类方法中,任何人都无法修改它。我已经定义了这样的接口和架构:

用户:

interface IUser {
  _id: string;
  name: string;
  email: string;
  created_at: number;
  updated_at: number;
  last_login: number;
}

还有架构:

let userSchema: Mongoose.Schema = new Mongoose.Schema({
   'name': String,
   'email': String,
   'created_at': {'type': Date, 'default': Date.now},
   'updated_at': {'type': Date, 'default': Date.now},
   'last_login': {'type': Number, 'default': 0},
});

interface UserDocument extends IUser, Mongoose.Document {}

然后是模型

// Model
let Users: Mongoose.Model<UserDocument> = Mongoose.model<UserDocument>('User', userSchema);

所以我只导出 IUser 和一个基本上具有更新模型的所有方法的类 User。

问题是,如果我将 _id 添加到我的界面,打字稿会抱怨,但我确实需要它,否则我将需要传递 UserDocument,这就是我不想做的。打字稿给我的错误是:

错误 TS2320:接口“UserDocument”不能同时扩展类型“IUser”和“Document”。 “IUser”和“Document”类型的命名属性“_id”不相同。

任何想法如何将 _id 属性添加到我的界面?

谢谢!

【问题讨论】:

  • 默认情况下,Mongoose 中的 _id 类型为 ObjectId (mongoose.Schema.Types.ObjectId)。
  • 嗨@robertklep,我已经尝试过,而不是字符串,它给了我同样的错误,只有当我输入 _id: any 它停止抱怨,但这并不理想。
  • 太糟糕了:(我对 TS 没有任何经验,所以恐怕无法进一步帮助你。

标签: node.js typescript mongoose


【解决方案1】:

我刚刚遇到了这个确切的问题,我想尽可能地将用户界面属性与 Mongoose 分开。我设法使用Omit 实用程序类型解决了这个问题。

这是您使用该类型的原始代码:

import { Document, Model, ObjectId } from 'mongoose';

export interface IUser {
  _id: ObjectId;
  name: string;
  email: string;
  created_at: number;
  updated_at: number;
  last_login: number;
}

export interface IUserDocument extends Omit<IUser, '_id'>, Document {}
export interface IUserModel extends Model<IUserDocument> {}

【讨论】:

    【解决方案2】:

    试试这个:

    const UserSchema: Schema = new Schema(
      {
       ..
      }
    );
    type UserDoc = IUser & Document;
    
    export interface UserDocument extends UserDoc {}
    
    // For model
    export interface UserModel extends Model<UserDocument> {}
    
    export default model<UserDocument>("User", UserSchema);
    

    【讨论】:

      【解决方案3】:

      试试:

      interface UserDocument extends IUser, Mongoose.Document {
         _id: string;
      }
      

      它将解决 IUser._id (string) 与 Mongoose.Document._id (any) 之间的冲突。

      更新

      正如 cmets 中所指出的,目前它给出了 incompatible override for member from "Document",因此必须使用另一种解决方法。 Intersection types 是一个可以使用的解决方案。也就是说,可以执行以下操作:

      type UserDocument = IUser & Mongoose.Document;
      

      或者,如果您不再需要UserDocument

      // Model
      let Users = Mongoose.model<IUser & Mongoose.Document>('User', userSchema);
      

      值得注意的是,这个解决方案有一个副作用。冲突的属性将具有相交的类型,例如,IUser._id (string) &amp; Mongoose.Document._id (any) 的结果为 UserDocument._id (any)

      【讨论】:

      • 你确定?这给了incompatible override for member from "Document"
      • 你能解释一下冲突的部分吗? It is worth noting that there is a side effect in this solution. The conflicting properties will have the types intersected, so IUser._id (string) &amp; Mongoose.Document._id (any) results in UserDocument._id (any),
      猜你喜欢
      • 2019-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-07
      • 2020-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多