typescript - 如何在打字稿中定义续集关联?
问题描述
我有一个 Product 表和一个 AccountingPeriod 表,其属于从Product.manufacturingPeriodId到 AccountingPeriod.id 的关系。
下面的代码编译但因“模型产品上的属性'manufacturingPeriod'和关联'manufacturingPeriod'之间的命名冲突。要解决这个问题,请在运行时更改foreignKey或在您的关联定义中” 。
如果我as
按照指示更改最底部的关联代码,我也会炸毁,但这次“AccountingPeriod 使用别名与 Product 关联。您已包含别名 (accountingPeriod),但它与别名不匹配在您的协会中定义”。第二条错误消息尤其令人费解,因为我没有指定名为accountingPeriod的别名。
嗬!对我来说似乎是 Catch-22。
当然,我可以在调用 sequelize.define() 的选项对象中删除ProductAttributes.manufacturingPeriod
、放回manufacturingPeriodId: number;
和重命名manufacturingPeriod
回。manufacturingPeriodId
编译和运行都很好,但是我不能myproduct.manufacturingPeriod.startDate
在打字稿中编写类似的代码。
我尝试了各种其他方法。一切都失败了,所以我要举起投降的白旗。谁能帮我吗?我有 sequelize 的经验,但对 typescript 来说相对较新,我只是没有看到它。
import * as Sequelize from 'sequelize';
import {ObjectRelationalManager as orm} from '../index';
import {AccountingPeriodInstance} from './accounting-period';
export interface ProductAttributes {
id?: number;
name: string;
manufacturingPeriod: AccountingPeriodInstance;
}
export interface ProductInstance extends Sequelize.Instance<ProductAttributes>, ProductAttributes {}
export default (
sequelize: Sequelize.Sequelize,
dataTypes: Sequelize.DataTypes
): Sequelize.Model<ProductInstance, ProductAttributes> => {
return sequelize.define<ProductInstance, ProductAttributes>(
'Product',
{
id: {
type: dataTypes.INTEGER,
field: 'id',
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: dataTypes.STRING(20),
field: 'name',
allowNull: false
},
manufacturingPeriod: {
type: dataTypes.INTEGER,
field: 'manufacturingPeriodId',
allowNull: false,
references: {
model: 'AccountingPeriod',
key: 'id'
},
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION'
}
},
{
tableName: 'Product'
}
);
};
export function createAssociations(): void {
orm.Product.belongsTo(orm.AccountingPeriod, {
as: 'manufacturingPeriod',
// foreignKey: 'manufacturingPeriodId',
targetKey: 'id',
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION'
});
}
解决方案
自己找到了答案。
Sequelize 已经为关系创建了属性,因此只需在 ProductInstance 定义中为 typescript 编译器声明它们即可:
export interface ProductInstance extends Sequelize.Instance<ProductAttributes>, ProductAttributes {
manufacturingPeriod: AccountingPeriodInstance;
}
在调试时,我还注意到了方便的 getXXX、setXXX、createXXX、addXXX、removeXXX、hasXXX 和 countXXX 访问器函数,它们会自动为关系创建;我已经忘记了他们。经过一番挖掘,我在@types/sequelize 的类型定义文件中找到了他们的打字稿定义:
export interface ProductInstance extends Sequelize.Instance<ProductAttributes>, ProductAttributes {
manufacturingPeriod: AccountingPeriodInstance;
getAccountingPeriod: Sequelize.BelongsToGetAssociationMixin<AccountingPeriodInstance>;
setAccountingPeriod: Sequelize.BelongsToSetAssociationMixin<AccountingPeriodInstance, number>;
createAccountingPeriod: Sequelize.BelongsToCreateAssociationMixin<AccountingPeriodAttributes>;
}
在这种特殊情况下,关系是 belongsTo,所以 getXXX、setXXX、createXXX 是仅有的 3 个函数。但还有更多以 , 等形式{RelationShipType}{Add}AssociationMixin<TInstance>
存在{RelationShipType}{Remove}AssociationMixin<TInstance>
。
推荐阅读
- python - 如何让 random.choice 返回 2 个不同的值?
- c++ - 我们如何并行运行 n 个算法实例并以有效的方式计算结果函数的平均值?
- ruby-on-rails - 峰会按钮在 rails form_with 编辑操作中不起作用
- php - 此页面无法正确加载 Google 地图
- testing - 邮递员中的断言以检查日期格式
- c++11 - 如何调用完全专用的重载运算符?
- mongodb - MongoDB仅聚合标准偏差内的数据
- javascript - 我似乎无法正确解析 JS 中的 XML 数据
- android - 找不到 com.android.tools.build:gradle:3.0.1。在尝试构建 tensorflow lite 演示应用程序时
- linux - cygwin 和 Linux - 未设置 $USER 时获取当前用户