Home > Back-end >  How to export mongoose model using typescript?
How to export mongoose model using typescript?

Time:08-31

I have the following module which I need to export in a way as to avoid the error of " OverwriteModelError: Cannot overwrite Task model once compiled".

I've seen many answers explain this but I can't get it to work. The last line is the issue (the export default models...

import { Schema, model, models } from 'mongoose';

export interface ITask {
    title: string;
    description: string;
}

const TaskSchema = new Schema<ITask>({ 
    title: {type: String},
    description: {type: String}
            
},{
    timestamps: true,
    versionKey: false
}) 

export default  models['Task']<ITask>  ||  model<ITask>('Task', TaskSchema); 

I added models['Task']<ITask> randomly because everything I tried doesn't seem to work

When I import that module and use it

const tasks = await Task.find();

It gives a typescript error which I don't understand: Each member of the union type... has signatures, but none of those signatures are compatible with each other


EDIT

At pages/api/tasks/[id].ts I have this

import { dbConnect, runMiddleware } from "@db/index";
import Task from "@model/Task";
dbConnect();
const SingleTask: NextApiHandler = async (req, res) => {
    const { method, body, query: {id} } = req;
    const morgan = Morgan("dev");
  
    switch (method) {
      case "GET":
        try {
          const task = await Task.findById(id);
....

At pages/api/tasks/index.ts I have this

import { dbConnect, runMiddleware } from "@db/index";
import Task from "@model/Task";
dbConnect();
const Tasks: NextApiHandler = async (req, res) => {
  const { method, body } = req;
  const morgan = Morgan("dev");

  switch (method) {
    case "GET":
      try {
        const tasks = await Task.find();
....

And the dbConnect method refers to this

import { connect, connection, ConnectionStates } from "mongoose";
interface ConnectionInterface {
  isConnected: ConnectionStates;
}
const conn: ConnectionInterface = {
  isConnected: 0,
};
export async function dbConnect() {
  if (conn.isConnected === 1) return;
  const db = await connect(process.env.MONGODB_URI);
  conn.isConnected = db.connections[0].readyState;
  console.log("Connected to database", db.connection.db.databaseName);
}

CodePudding user response:

As long as you're only creating the Task model in one place, you should really only need the following...

export default model<ITask>("Task", TaskSchema);

However if you want to check for existing Task models before compilation, use something like this

import { Model, Schema, model, models } from "mongoose";

// ...

const Task = models.Task as Model<ITask> ?? model<ITask>("Task", TaskSchema);
export default Task;
  • Related