猫鼬+打字稿 - >导出模型界面

时间:2016-06-20 15:37:41

标签: node.js typescript mongoose

我想只导出我的模型的接口而不是Document,这样如果不是在自己的类方法中,没有人可以修改我的模型。我已经定义了这样的接口和模式:

IUSER:

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和一个类用户,基本上有所有方法来更新我的模型。

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

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

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

谢谢!

3 个答案:

答案 0 :(得分:9)

尝试:

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

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

<强>更新

正如评论中所指出的,目前它提供了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) & Mongoose.Document._id (any)会导致UserDocument._id (any),例如。

答案 1 :(得分:0)

尝试一下:

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);

答案 2 :(得分:0)

我刚刚遇到了这个确切的问题,我希望尽可能将用户界面属性与 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> {}