不兼容的类型。 'this'可以用任意类型实例化,而这可能是不相关的。 。

时间:2020-10-16 03:44:52

标签: typescript typescript-generics

我正在将Sequelize与一些第三方库生成的接口用于我的各种表,以使Sequelize在TypeScript应用程序中确实能很好地工作。

Sequelize提供了一个接口Instance<A>,它表示对SELECT ... LIMIT 1查询的查找结果。它具有该行的所有列以及各种帮助程序,如toJSON(),该方法仅返回没有帮助程序的列的JSON表示形式。

我的3PL生成的接口代表我所有表的实例以及我所有表的属性,以及一堆我省略的好东西。

在我的代码中,我想运行Sequelize查询(返回一个Promise<Instance<A>>),然后调用toJSON()函数,以便我的数据服务返回数据的JSON表示,而没有诸如toJSON(这样我就可以序列化数据并通过HTTP发送)。实际上,返回attributes(仅是列数据)而不是instance(列数据以及各种不可序列化的内容,例如方法和循环数据)。

我想创建一个接受实例并返回属性的函数extractData: (Instance<A>) => A,以便可以执行query().then(extractData)而不是query().then(result => result.toJSON())。这是为了提高可读性。

但是,我的extractData函数Argument of type '<A>(data:Instance<A>)=>A' is not assignable to parameter of type '(a:tableInstance)=>tableAttribute'. Types of parameter 'data' and 'a' are incompatible. Types of property 'Model' are incompatible. /*snip*/ 'this' could be instantiated with an arbitrary type which could be unrelated to 'tableInstance'遇到错误。

我不明白他们在说什么不兼容的类型。此外,如果我编写的辅助接口是Instance的简化形式,称为$Instance,仅具有toJSON方法,然后在我的extractData函数中使用该接口,错误消失了。为什么?

在SO上还有许多与此问题类似的问题,但是它们的变化都稍有不同,例如人们将泛型与类名混淆(我在这里没有做过)。我找不到一个合适的答案(实际上,我花了二十分钟通过许多问题,然后花三十分钟来撰写自己的问题;找到一个已经回答的问题比写这个问题要快得多)。

(我也可以尝试query().then(extractData.bind(extractData))来使错误消失,但是TypeScript将返回值检测为unknown而不是tableAttribute。)

有关我所讨论内容的简化代码,请参见下文:

// simplified for this SO post from Sequelize types 3.30.4
interface Model<I, A> /*extends some interfaces*/ {
  /* some props, methods */
}
interface Instance<A> {
  Model: Model<this, A>
  toJSON(): A
}

// 3PL-generated sequelize typescript interfaces/types
interface tableAttribute { /* models SQL table */
  id: number
  foo: string
  bar: string
}

interface tableInstance extends Instance<tableAttribute>, tableAttribute { }

// My code
interface $Instance<A> {
  toJSON(): A
}

const extractData = <A>(data: Instance<A>) => data.toJSON() // Instance<A> => A
const $extractData = <A>(data: $Instance<A>) => data.toJSON() // $Instance<A> => A

declare const getData: () => Promise<tableInstance>

const fetch = () => getData().then(extractData) // ERROR!
const $fetch = () => getData().then($extractData) // () => Promise<tableAttribute>

0 个答案:

没有答案