0

I'm trying to import an object from a typescript to another typescript file. Here's my code:

import mongoose from "mongoose";
import Note from './models/notes';
import User from './models/users';
import express, { Request, Response } from 'express';
import cors from 'cors';
import dotenv from 'dotenv';

dotenv.config();

const app = express();

app.use(cors());
app.use(express.json());

const PORT = process.env.PORT || 5000;
const URI = process.env.ATLAS_URI as string;

const connectToDB = async () => {
    try {
        await mongoose.connect(URI);
        console.log('Connected to MongoDB');
        app.listen(PORT, () => console.log(`Server running on port: ${PORT}`));
    } catch (err) {
        console.log(err);
    }
};
connectToDB();

My file structure is

server
    /dist
        index.js
        /models
            users.js
            notes.js
    /node_modules
    /src
        index.ts
        /models
            users.ts
            notes.ts
    package.json
    package-lock.json
    .env
    tsconfig.json

(I'm not using webpack or babel)

I tried to do something like this:

import User from '../dist/models/users.js'

or this

import User from './models/notes.js

but that gives me errors and I'm pretty sure it isn't the right way to do it.

Btw, here's my tsconfig.json

{
    "compilerOptions": {
        "target": "ES2022",
        "module": "ES2022",
        "rootDir": "./src",
        "outDir": "./dist"
        "moduleResolution": "node",
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true
    }
}

What am I missing?

Edit 1 Here's my users.ts file:

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

interface IUser {
    email: string;
    password: string;
}

interface IUserModel extends IUser, Document { }

const UserSchema = new Schema({
    email: { type: String, required: true, unique: true },
    password: { type: String, required: true },
}, { timestamps: true });

const User = model<IUserModel>('User', UserSchema);

export default User;

Edit 2 I get this error:

Cannot find module '...\server\dist\models\users' imported from '...\server\dist\index.js'

The typescript import is compiled to js like this:

import User from './models/users';

Edit 3 Here's my package.json

{
    "name": "server",
    "version": "1.0.0",
    "description": "",
    "main": "",
    "type": "module",
    "scripts": {
        "start:ts": "tsc -w",
        "start:js": "concurrently \"nodemon dist/index.js\" \"nodemon dist/models/users.js\" \"nodemon dist/models/notes.js\" ",
        "start": "concurrently npm:start:*"
    },
    "keywords": [],
    "author": "Alex",
    "license": "ISC",
    "dependencies": {
        "@types/cors": "^2.8.13",
        "@types/express": "^4.17.17",
        "@types/mongoose": "^5.11.97",
        "concurrently": "^8.0.1",
        "cors": "^2.8.5",
        "express": "^4.18.2",
        "mongoose": "^7.0.3"
    }
}
Alexxino
  • 557
  • 2
  • 16

1 Answers1

0

Since you're using type=module, you need to use the .js extension, see type in package.json and New Extensions

I tried to reproduce your example and got it running by adding the .js using the following dependencies:

    ...
    "nodemon": "^2.0.22",
    "tsc": "^2.0.4",
    "typescript": "^5.0.4"

Tested it with both node v16 & v19. My guess is that you're using an outdated typescript/node version that did not fully support ESM they way it currently is. Also please note that you should use await connectToDB(); to wait for the setup to finish.

Mirco
  • 171
  • 5