如何使用 TypeScript 正确键入 Sequelize JOIN?

Posted

技术标签:

【中文标题】如何使用 TypeScript 正确键入 Sequelize JOIN?【英文标题】:How do I correctly type Sequelize JOINs using TypeScript? 【发布时间】:2018-10-24 00:18:59 【问题描述】:

我正在尝试在 Sequelize 中将两个表连接在一起:

const results = await MainModel.findAll( include: [ JoinedModel ] );

但是,当我尝试访问连接表中的数据时,TypeScript(至少在 --strict 模式下)会报错:

const joinedField = results[0].joinedModel.joinedField;

导致:

Property 'joinedModel' does not exist on type 'Instance<MainModelAttributes>'.

尽管有 TypeScript 的抱怨,但上面的代码确实实际上为我提供了连接字段中的值。

输入这个的正确方法是什么? (我在这里正确使用 Sequelize 吗?)

【问题讨论】:

【参考方案1】:

那是因为findAll 的结果是一个 Promise。试试这个:

MainModel.findAll( include: [ JoinedModel ] ).then(result => 
 your code here...
);

【讨论】:

糟糕,我在为这个问题修剪代码时犯了一个错误。然而,这不是问题 - 代码确实有效,只是 TypeScript 在抱怨。 在处理 Promise 的结果时,不应该有任何抱怨……此外,您可以将结果显式转换为您想要的类型。 嗯,有...(我将更新帖子以添加我正在使用 TypeScript 的严格模式。)当然可以进行显式转换,但我宁愿将类型设为正确推断以避免自己引入错误。【参考方案2】:

您可以这样做,因为 sequelize 函数会将结果作为模型实例返回,其中包含 sequelize 元数据,因此通过对响应进行字符串化和解析,您可以获得结果的 JSON 表示形式。

let results = await MainModel.findAll( include: [ JoinedModel ] );
results = JSON.parse(JSON.stringify(results));
const joinedField = results[0].joinedModel.joinedField;

您可以使用查询选项 raw 以纯 json 格式获取响应。

let results = await MainModel.findAll(raw: true, include: [ JoinedModel ] );

参考:Sequelize Doc

【讨论】:

感谢@Imrahamed,但我不需要结果的 JSON 表示 - 我展示的代码已经工作。我需要(ed)的是让 TypeScript 理解它,而不是它吐出我显示的错误消息。 const 结果:any = await MainModel.findAll( include: [ JoinedModel ] );您可以将 type 定义为 any 以防止该错误。 是的,any 是一种避免打字的方法,这就是我为解决这个问题所做的工作。但是,我更愿意正确输入它,这就是这个问题的意义所在......【参考方案3】:

您可以通过这种方式转换结果。

const results = await MainModel.findAll( include: [ JoinedModel ] ) as Array<MainModel & JoinedModel: JoinedModel>;

【讨论】:

以上是关于如何使用 TypeScript 正确键入 Sequelize JOIN?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Typescript 在 mongoose 中正确键入对象 ID 数组

如何使用 TypeScript 正确键入检查允许部分子树的嵌套记录?

如何在 Typescript 中使用 redux-thunk 使用 ThunkAction 正确键入 thunk?

如何在 TypeScript 3+ 中正确键入通用元组剩余参数?

如何正确键入返回 TypeScript 中的类的函数?

TypeScript:如何正确键入一个接受承诺并按原样返回该承诺的函数