繁体   English   中英

全新的 TypeScript,尝试使用 Sequelize

[英]Brand new to TypeScript, trying to use Sequelize

我是 TypeScript 的新手,我正在尝试使用 Sequelize 和 Sequelize Auto 来生成数据库模型,然后使用它们进行查询。

到目前为止,模型已经生成,但是当我尝试实际使用它们时,出现错误。

/* jshint indent: 2 */
// tslint:disable
import * as sequelize from 'sequelize';
import {DataTypes} from 'sequelize';
import {settings_user_tblInstance, settings_user_tblAttribute} from './db';

module.exports = function(sequelize: sequelize.Sequelize, DataTypes: DataTypes) {
  return sequelize.define<settings_user_tblInstance, settings_user_tblAttribute>('settings_user_tbl', {
    id: {
      type: DataTypes.BIGINT,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    user_id: {
      type: DataTypes.BIGINT,
      allowNull: true,
      references: {
        model: 'user_tbl',
        key: 'id'
      },
      unique: true
    },
    notification_email_enabled: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
      defaultValue: true
    }
  }, {
    tableName: 'settings_user_tbl'
  });
};

但是,在尝试使用此模型时,出现以下错误:

   return sequelize.define<settings_user_tblInstance, settings_user_tblAttribute>('settings_user_tbl', {


src/models/tag_group_tbl.ts:7:70 - error TS2709: Cannot use namespace 'DataTypes' as a type.

 module.exports = function(sequelize: sequelize.Sequelize, DataTypes: DataTypes) {

我对这两个错误都很迷茫 - 看起来 DataTypes 定义正确吗? 这就是 Sequelize Auto 生成文件的方式 - 这样做是否不正确?

为什么它只需要 0 个参数而不是 2 个参数?

这可能是版本不兼容的事情吗?

很抱歉这个毫无头绪的问题 - 我真的刚刚开始使用 TypeScript,我不完全确定这里发生了什么。

有人在sequelize-auto repo 上遇到了完全相同的问题,最终fork了 repo,他最近似乎真的很活跃:值得一试他的版本,看看它是否解决了问题,他实际上在原始版本中关闭了问题回购😃

但我建议您尝试切换到TypeormTypeorm-model-generator,因为它从一开始就是面向 Typescript 的。

老实说,目前对sequelize-auto TS 支持确实不好,生成器会创建错误的类型。

最后一个版本也是两年前发布,人们分叉并发布了他们自己的包,所以我不确定它是否正在积极开发中。 您仍然可以让sequelize-auto创建样板列定义、类属性等,并手动将它们复制到您的模型中(稍后)。

首先,使用-z选项运行sequelize-auto以创建类型定义。 例子:

npx sequelize-auto -h localhost -u dontcare -d my-db.db --dialect sqlite -z

给定数据库中的user表, sequelize-auto生成文件user.tsmodels下的其他文件,其中包含您已经遇到的一堆 TS 编译错误。 例如DataTypes是一个命名空间,但在函数参数中用作类型,在sequelize.define函数上设置泛型,其中根本不需要泛型。

此外sequelize-auto创建了模型定义sequelize.define 我宁愿坚持使用 class 语法,如 sequelize TypeScript docs 部分的第一部分所示 - 它产生更多可读性和更容易声明类型。

所以,总而言之,坚持上面的教程更有意义,复制我们需要的代码,然后再次删除生成的文件。 有用的代码是生成的表列定义和类属性:

user.ts复制所有表列属性,如id: { type: DataTypes.INTEGER, allowNull: true, primaryKey: true }等。 db.d.ts ,应该有类似userAttribute接口的东西,从中可以使用类属性。 最后,通过类语法在某处创建模型:

import { Sequelize, Model } from 'sequelize';

// your models 
class User extends Model {
  // paste class attributes here
  // also add `null assertion` `!`, which is required in strict mode (see their docs)
}
...

初始化模型。 您还可以在此处粘贴生成的代码:

User.init({ /*pass column definitions*/ }

希望能帮助到你。

正如在问题中提到的@ Gomino的回答,一月一个新的选择被张贴:

import { Sequelize, DataTypes } from 'sequelize';

module.exports = function(sequelize: Sequelize, _DataTypes: typeof DataTypes) {
  // return sequelize.define() ...
}

您可以设置任何名称而不是 _DataTypes,但是如果您尝试使用“DataTypes”,您将看到以下消息:

'DataTypes' 在它自己的类型 annotation.ts(2502) 中被直接或间接引用

作为替代方案,您可以重命名导入:

import { Sequelize, DataTypes as DataType } from 'sequelize';

module.exports = function(sequelize: Sequelize, DataTypes: typeof DataType) {
  // return sequelize.define() ...
}

或者

import { Sequelize, DataTypes } from 'sequelize';

type DataType = typeof DataTypes;
module.exports = function(sequelize: Sequelize, DataTypes: DataType) {
  // return sequelize.define() ...
}

我认为这不是在续集中使用 Typescript 的正确方法。 通常我们定义一个我们想要定义的模型的接口。

文档中实际上有一个打字稿实现的例子。 https://sequelize.org/master/manual/typescript.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM