🦔

【mongoose】Cannot overwrite 'Model' model once compiled. エラーの直し方

2021/07/12に公開

mongooseでモデルを定義したあと、ホットリロードなどをすると、次のようなエラーに遭遇します。

Cannot overwrite 'Model' model once compiled. 

モデルは次のように定義しています。

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

export interface UserDoc extends Document, {
  username: string
  email: string
  password: string
}

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

interface UserModel extends Model<UserDoc> {}

export default mongoose.model<UserDoc, UserModel>('User', userSchema)

mongooseでは、同じスキーマを使用してmongoose.model()で2度以上インスタンスを作成することができません。

次のように修正することでエラーを解消できます。

- import mongoose, { Schema, Document, Model } from 'mongoose'
+ import mongoose, { Schema, Document, Model, models } from 'mongoose'

export interface UserDoc extends Document, {
  username: string
  email: string
  password: string
}

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

interface UserModel extends Model<UserDoc> {}

- export default mongoose.model<UserDoc, UserModel>('User', userSchema)
+ export default models.User
+   ? (models.User as UserModel)
+   : mongoose.model<UserDoc, UserModel>('User', userSchema)

mongoosemodelsは、すでに登録済のモデル名をキーとして取得できます。

modelsにすでに存在するには、それをexportすることによって、同じモデルを再登録することによる生じるエラーを解消することができます。

TypeScriptを使用している場合、modelsに登録されているモデルはstaticsなどをモデルに追加している場合正しい型が得られないので型アサーションをする必要があるでしょう。

modelsに登録されていなかった場合、通常通りモデルを作成してexportします。

GitHubで編集を提案

Discussion