【问题标题】:Generic types within an interface for a function type函数类型的接口中的泛型类型
【发布时间】:2020-07-31 13:44:17
【问题描述】:

在为选项对象创建接口时,我试图允许用户指定具有显式返回类型和通用参数类型的函数。如果您事先没有为函数定义类型,这是可能的,但我不知道如何为您已经定义的函数类型执行此操作。

例如,这很好用:

interface Options {
  // Other options...
  converterFunction: <T>(rawData: T) => [];
}

但这似乎是一种合理的语法,但事实并非如此。

type ConverterFunction<T> = (rawData: T) => [];

interface Options {
  // Other options...
  converterFunction: <T>ConverterFunction<T>; // TypeScript is unhappy
}

使接口通用并不能解决我的问题,我想使用我的预定义类型而不是随意重新定义它们。

【问题讨论】:

  • ConverterFunction&lt;T&gt;类型不是泛型函数,所以在定义Options时不能使用。您可能需要generic values 之类的东西以编程方式将引用特定函数的泛型类型转换为引用泛型函数的特定类型。但是该语言现在不支持该功能。据我所知,您必须重新定义您的类型。
  • 谢谢,@jcalz。所以澄清一下,如果一个泛型函数被命名,它就不再是泛型的了?
  • 不完全是。 type Foo = &lt;T&gt;(x: T)=&gt;T 是泛型函数的非泛型类型别名,而type Bar&lt;T&gt; = (x: T)=&gt;T 是非泛型函数的泛型类型别名。您可以同时拥有:type Baz&lt;T&gt; = &lt;U&gt;(x: T, y: U) =&gt; [T, U]。问题是 TS 中有两种不同类型的泛型,它们根据泛型参数的范围和指定它的人而有所不同。通用函数在调用签名上有一个参数,调用者指定它。泛型类型别名/接口/类在定义中有参数,后面引用时会指定。
  • 谢谢!我切换到另一个帐户,所以我认为我还没有能力因为声誉而投票,但这是非常有帮助的澄清!

标签: typescript generics types interface


【解决方案1】:

使用另一种泛型类型的类型必须传递一个具体类型,或者本身就是泛型。

&lt;T&gt;Type&lt;T&gt; 不是有效的语法。

type ConverterFunction<T> = (rawData: T) => [];

interface Options<T> {
  converterFunction: ConverterFunction<T>; // TypeScript is happy
}

const options: Options<string> = {
  converterFunction(aString) {
    return []
  }
}

Playground


如果类型没有命名,你可以定义一个带有泛型参数的函数,但是如果有命名,这似乎是不可能的。我在问是否确实如此

这完全取决于您希望传入的泛型级别。

如果你在使用类型的时候就知道了,那么就继续使用类型。

type ConverterFunction<T> = (rawData: T) => T[];
const fn: ConverterFunction<string> = a => [a]
fn('a') // ['a']

或者如果你想要函数本身推断的泛型类型,那么把它放在函数上。

type ConverterFunction = <T>(rawData: T) => T[];
const fn: ConverterFunction = (a: string) => [a]
fn('a') // ['a']

读完你的 cmets,听起来你想要第二个。

【讨论】:

  • 为什么&lt;T&gt;(rawData: T) =&gt; [] 是有效的语法?这似乎允许您在定义函数时指定类型而不是类型范围。
  • &lt;T&gt;(args: ArgsType) =&gt; ReturnType 是您声明泛型函数类型的方式。如果该类型已经有名称,则泛型参数在最后。这就是语法的工作原理。在这两种情况下,它都只是简单地声明了泛型参数。
  • 是的,我不是在质疑语法。如果类型没有命名,你可以定义一个带有泛型参数的函数,但如果它被命名,似乎这是不可能的。我在问是否确实如此。
  • 感谢您的澄清!我已经切换了帐户,因此我还没有为你投票的声誉,但我已将此标记为答案。
猜你喜欢
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 2013-07-05
  • 1970-01-01
相关资源
最近更新 更多