This article was translated from Japanese by AI and may contain inaccuracies. For the most accurate content, please refer to the original Japanese version.
Node.js

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

mongooseで遭遇するCannot overwrite 'Model' model once compiled. エラーの解消方法です

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 します。