How to make Typescript transpile my Sequelize model?

假如想象 提交于 2021-02-11 14:25:19

问题


After transpiling the code using the command "yarn tsc", I tried to execute my code and got the error in the image below. When I went to check the reason for the error, I saw that my Sequelize model classes are not being stacked, they are empty. I couldn't find explanations anywhere about the reason for this, nor in the Sequelize documentation. Could anyone help?

My dependencies

"dependencies": {
        "@babel/plugin-proposal-class-properties": "^7.8.3",
        "@types/bcrypt": "^3.0.0",
        "@types/cors": "^2.8.6",
        "@types/jsonwebtoken": "^8.5.0",
        "@types/moment": "^2.13.0",
        "@types/nodemailer": "^6.4.0",
        "@types/ws": "^7.2.4",
        "axios": "^0.19.2",
        "bcrypt": "^4.0.1",
        "cep-promise": "^3.0.9",
        "class-transformer": "^0.2.3",
        "class-validator": "^0.12.2",
        "cors": "^2.8.5",
        "discord.js": "^12.2.0",
        "dotenv": "^8.2.0",
        "express": "^4.17.1",
        "jsonwebtoken": "^8.5.1",
        "jwt-then": "^1.0.1",
        "melif": "^1.0.6",
        "moment": "^2.25.3",
        "mysql2": "^2.1.0",
        "nodemailer": "^6.4.6",
        "reflect-metadata": "^0.1.13",
        "sequelize": "^5.21.5",
        "sequelize-cli": "^5.5.1",
        "sequelize-cli-typescript": "^3.2.0-c",
        "ts-node": "^8.10.1",
        "typescript": "^3.9.2"
    },
    "devDependencies": {
        "@babel/cli": "^7.8.4",
        "@babel/core": "^7.9.6",
        "@babel/plugin-transform-runtime": "^7.9.6",
        "@babel/preset-env": "^7.9.6",
        "@babel/preset-typescript": "^7.9.0",
        "@babel/register": "^7.9.0",
        "@types/bluebird": "^3.5.30",
        "@types/express": "^4.17.6",
        "@types/node": "^14.0.1",
        "@types/sequelize": "^4.28.9",
        "@types/validator": "^12.0.1",
        "@typescript-eslint/eslint-plugin": "^2.33.0",
        "@typescript-eslint/parser": "^2.33.0",
        "eslint": "^7.0.0",
        "eslint-config-standard": "^14.1.1",
        "eslint-plugin-import": "^2.20.2",
        "eslint-plugin-node": "^11.1.0",
        "eslint-plugin-promise": "^4.2.1",
        "eslint-plugin-standard": "^4.0.1",
        "nodemon": "^2.0.4",
        "sucrase": "^3.15.0",
        "typescript": "^3.9.2"
    }

My 'tsconfig.json'

{
  "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node",
    //"esModuleInterop": true,
    "resolveJsonModule": true,
    "experimentalDecorators": true,
    "outDir": "./dist",
    "target": "es6",
    //"noEmit": true,
    //"allowSyntheticDefaultImports": true,
    "types": [
      "node"
    ]
  },
  "include": [
    "src"
  ],
  "exclude": [
    "node_modules"
  ],
  "compileOnSave": false
}

Class User.ts

import { Sequelize, Model, DataTypes, HasManyGetAssociationsMixin, HasManyAddAssociationMixin, HasManyHasAssociationMixin, Association, HasManyCountAssociationsMixin, HasManyCreateAssociationMixin, BelongsToManyGetAssociationsMixin, BelongsToManyAddAssociationMixin, BelongsToManyHasAssociationMixin, BelongsToManyCountAssociationsMixin, BelongsToManyCreateAssociationMixin, HasManyRemoveAssociationMixin } from 'sequelize'
import { Route } from './Route'
import { Company } from './Company'
import { Account } from './Account'

import { DoneRoute } from './DoneRoute'
import { DoneLesson } from './DoneLesson'
import { Payment } from './Payment'

export interface UserI {
  id?: number | null;
  name: string;
  email: string;
  password: string;
  introduced: boolean;
  paid_access_expiration: Date;
}
export class User extends Model implements UserI {
  public id?: number | null;
  public name!: string;
  public email!: string;
  public password!: string;
  public introduced!: boolean;
  public paid_access_expiration!: Date;

  public getRoutes!: BelongsToManyGetAssociationsMixin<Route>; // Note the null assertions!
  public addRoute!: BelongsToManyAddAssociationMixin<Route, number>;
  public hasRoute!: BelongsToManyHasAssociationMixin<Route, number>;
  public removeRoute!: HasManyRemoveAssociationMixin<Route, number>;
  public countRoutes!: BelongsToManyCountAssociationsMixin;
  public createRoute!: BelongsToManyCreateAssociationMixin<Route>;

  public getCompanies!: BelongsToManyGetAssociationsMixin<Company>; // Note the null assertions!
  public addCompany!: BelongsToManyAddAssociationMixin<Company, number>;
  public hasCompany!: BelongsToManyHasAssociationMixin<Company, number>;
  public removeCompany!: HasManyRemoveAssociationMixin<Company, number>;
  public countCompanies!: BelongsToManyCountAssociationsMixin;
  public createCompany!: BelongsToManyCreateAssociationMixin<Company>;

  public getDoneRoutes!: HasManyGetAssociationsMixin<DoneRoute>; // Note the null assertions!
  public addDoneRoute!: HasManyAddAssociationMixin<DoneRoute, number>;
  public hasDoneRoute!: HasManyHasAssociationMixin<DoneRoute, number>;
  public removeDoneRoute!: HasManyRemoveAssociationMixin<DoneRoute, number>;
  public countDoneRoutes!: HasManyCountAssociationsMixin;
  public createDoneRoute!: HasManyCreateAssociationMixin<DoneRoute>;

  public getDoneLessons!: HasManyGetAssociationsMixin<DoneLesson>; // Note the null assertions!
  public addDoneLesson!: HasManyAddAssociationMixin<DoneLesson, number>;
  public hasDoneLesson!: HasManyHasAssociationMixin<DoneLesson, number>;
  public removeDoneLesson!: HasManyRemoveAssociationMixin<DoneLesson, number>;

  public countDoneLessons!: HasManyCountAssociationsMixin;
  public createDoneLesson!: HasManyCreateAssociationMixin<DoneLesson>;

  public getAccounts!: HasManyGetAssociationsMixin<Account>; // Note the null assertions!
  public addAccount!: HasManyAddAssociationMixin<Account, number>;
  public hasAccount!: HasManyHasAssociationMixin<Account, number>;
  public removeAccount!: HasManyRemoveAssociationMixin<Account, number>;
  public countAccounts!: HasManyCountAssociationsMixin;
  public createAccount!: HasManyCreateAssociationMixin<Account>;

  public getPayments!: HasManyGetAssociationsMixin<Payment>; // Note the null assertions!
  public addPayment!: HasManyAddAssociationMixin<Payment, number>;
  public hasPayment!: HasManyHasAssociationMixin<Payment, number>;
  public removePayment!: HasManyRemoveAssociationMixin<Payment, number>;
  public countPayments!: HasManyCountAssociationsMixin;
  public createPayment!: HasManyCreateAssociationMixin<Payment>;

  public readonly routes?: Route[];
  public readonly companies?: Company[];
  public readonly done_routes?: DoneRoute[];
  public readonly done_lessons?: DoneLesson[];
  public readonly accounts?: Account[];
  public readonly payments?: Payment[];

  // timestamps!
  public readonly createdAt!: Date;
  public readonly updatedAt!: Date;

  public static associations: {
    routes: Association<User, Route>;
    companies: Association<User, Company>;
    done_routes: Association<User, DoneRoute>;
    done_lessons: Association<User, DoneLesson>;
    accounts: Association<User, Account>;
    payments: Association<User, Payment>;

  };
}
export function init (sequelize: Sequelize): void {
  User.init(
    {
      id: {
        type: DataTypes.INTEGER.UNSIGNED,
        autoIncrement: true,
        primaryKey: true
      },
      name: {
        type: DataTypes.STRING,
        allowNull: false
      },
      email: {
        type: DataTypes.STRING,
        allowNull: false
      },
      password: {
        type: DataTypes.STRING,
        allowNull: false
      },
      introduced: {
        type: DataTypes.BOOLEAN,
        defaultValue: false,
        allowNull: true
      },
      paid_access_expiration: {
        type: DataTypes.DATE,
        allowNull: false
      }

      // Colocar Relações
    },
    {
      tableName: 'users',
      sequelize: sequelize // this bit is important
    }
  )
}

export function associate (sequelize: Sequelize): void {
  User.belongsToMany(sequelize.models.Route, { foreignKey: 'user_id', through: 'user_routes', as: 'routes' })
  User.belongsToMany(sequelize.models.Company, { foreignKey: 'user_id', through: 'user_companies', as: 'companies' })
  User.hasMany(sequelize.models.DoneLesson, { foreignKey: 'user_id', as: 'done_lessons' })
  User.hasMany(sequelize.models.DoneRoute, { foreignKey: 'user_id', as: 'done_routes' })
  User.hasMany(sequelize.models.Account, { foreignKey: 'user_id', as: 'accounts' })
  User.hasMany(sequelize.models.Payment, { foreignKey: 'user_id', as: 'payments' })
}

Class User.js after command "yarn tsc"

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.associate = exports.init = exports.User = void 0;
const sequelize_1 = require("sequelize");
class User extends sequelize_1.Model {
}
exports.User = User;
function init(sequelize) {
    User.init({
        id: {
            type: sequelize_1.DataTypes.INTEGER.UNSIGNED,
            autoIncrement: true,
            primaryKey: true
        },
        name: {
            type: sequelize_1.DataTypes.STRING,
            allowNull: false
        },
        email: {
            type: sequelize_1.DataTypes.STRING,
            allowNull: false
        },
        password: {
            type: sequelize_1.DataTypes.STRING,
            allowNull: false
        },
        introduced: {
            type: sequelize_1.DataTypes.BOOLEAN,
            defaultValue: false,
            allowNull: true
        },
        paid_access_expiration: {
            type: sequelize_1.DataTypes.DATE,
            allowNull: false
        }
        // Colocar Relações
    }, {
        tableName: 'users',
        sequelize: sequelize // this bit is important
    });
}
exports.init = init;
function associate(sequelize) {
    User.belongsToMany(sequelize.models.Route, { foreignKey: 'user_id', through: 'user_routes', as: 'routes' });
    User.belongsToMany(sequelize.models.Company, { foreignKey: 'user_id', through: 'user_companies', as: 'companies' });
    User.hasMany(sequelize.models.DoneLesson, { foreignKey: 'user_id', as: 'done_lessons' });
    User.hasMany(sequelize.models.DoneRoute, { foreignKey: 'user_id', as: 'done_routes' });
    User.hasMany(sequelize.models.Account, { foreignKey: 'user_id', as: 'accounts' });
    User.hasMany(sequelize.models.Payment, { foreignKey: 'user_id', as: 'payments' });
}
exports.associate = associate;


回答1:


It was quite some time ago when I think I ran into this issue - but none-the-less - posting my (vaguely) remembered solution might still be helpful.

My models are in a "models" folder - and so I excluded the @babel/plugin-proposal-class-properties babel plugin from compiling that folder.

I do not remember why there is a loose: true option set. Try with/without it and see if it changes the behavior.

There is a bug logged - https://github.com/sequelize/sequelize/issues/10579 - allegedly closed (as at January 2021) - but it doesn't really seem to be solved.

{
  "env": {
    "development": {
      "presets": [
        [
          "next/babel"
        ]
      ],
      "plugins": [
        [
          "@babel/plugin-proposal-class-properties",
          {
            "exclude": "models",
            "loose": true
          }
        ]
      ]
    },
    "production": {
      "presets": [
        "next/babel"
      ],
      "plugins": [
        [
          "@babel/plugin-proposal-class-properties",
          {
            "exclude": "models",
            "loose": true
          }
        ]
      ]
    },
  ...
}


来源:https://stackoverflow.com/questions/61960885/how-to-make-typescript-transpile-my-sequelize-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!