我正在使用带有 Sequelize 模型的 JavaScript 代码库,该模型具有使用 TypeScript 声明文件记录的类型 (
.d.ts
)。我正在使用 mode.update()
来更新对象的一些属性:
这个问题可以重现如下:
import { Model } from "sequelize";
let model: Model<{foo:number,bar:string,baz:boolean}>;
model.update({
// start typing "foo", "bar", or "baz" and observe
// that suggestions do not appear.
})
我预计当开始输入“foo”、“bar”或“baz”时,我会得到建议来完成我在作为
TModelAttributes
泛型参数传递的内容中声明的那些字段。相反,它根本不会在建议列表中显示这些字段。
有趣的是,如果我在开始输入按键之前按 Ctrl+Space,它会按预期工作。
导致此问题的原因是什么,我该怎么做才能获得我期望的行为?
这是为sequelize 的
Model#update
方法发出的类型声明:
public update<K extends keyof TModelAttributes>(key: K, value: TModelAttributes[K] | Col | Fn | Literal, options?: InstanceUpdateOptions<TModelAttributes>): Promise<this>;
public update(
keys: {
[key in keyof TModelAttributes]?: TModelAttributes[key] | Fn | Col | Literal;
},
options?: InstanceUpdateOptions<TModelAttributes>
): Promise<this>;
如果我注释掉第一个重载,事情就会开始按照您希望的方式工作,因此这种重载使 ts-server 很难自信地给出您期望它给出的建议。
我认为您期望在这里实现的行为在逻辑上不是不可能的,因为可以通过以下事实来推断:我在第一个参数中将某些内容传递给
update
,而该内容已经无法匹配第一个重载update
(用于设置特定键值对的键值对),因为我在指定的 TModelAttributes
泛型参数中声明的键都不是对象类型,这应该意味着可以排除第一个重载,以及基于剩余可能的过载的建议。
但我认为,除了在问题单中向 TypeScript 维护者展示此 MRE 并询问是否可以在此处改进编辑器设施之外,您现在对此无能为力。问题单现已在 https://github.com/microsoft/TypeScript/issues/53069 提出。
...除非您从不使用
update
的键值重载,并且您决定从下载的续集类型减速文件中删除该行,但坦率地说,这只是一个糟糕的解决方案。每次您进行新的npm install
或更新软件包时,您都需要记住这样做。