TypeScript中的GeneratorFunction接口代表什么?

4

function* 声明(由 function 关键字后跟一个星号)定义了一个生成器函数,该函数返回一个 Generator 对象。 [参考]

但如果我写:

const genFn: GeneratorFunction = function* () {};

我理解为:

Property '[Symbol.toStringTag]' is missing in type '() => Generator<never, void, unknown>' but required in type 'GeneratorFunction'.ts(2741)
lib.es2015.symbol.wellknown.d.ts(161, 14): '[Symbol.toStringTag]' is declared here.

在TypeScript中,GeneratorFunction接口代表什么?此外,是否有更适合我捕获生成器函数的内置接口?


这是您提供的链接中也有记录的 GeneratorConstructor 类型。它是一个不同的类型。然而,正如错误所指示的那样,TypeScript 已经正确地推断出了生成器的类型,您的注释只是在与语言争论。把它去掉吧。换句话说,您的函数具有错误消息中显示的类型 () => Generator<never, void, unknown>,但您不需要将其写出来。 - Aluan Haddad
还有一种类型叫做GeneratorFunctionConstructor。这是你所指的吗?当然,我的实际代码并不像那个例子。我正在使用一个期望GeneratorFunction类型参数的库,但我无法构造出满足该类型的对象,这让我对这种接口的目的感到好奇。 - villasv
你说得对,我选错了类型,我想到的是构造函数类型。既然你提到了,我认为该类型的目的部分上是描述构造函数的类型。这就像“Function”类型一样,出于同样的原因不应直接使用。 - Aluan Haddad
有道理,这个接口确实被 GeneratorFunctionConstructor 使用。 - villasv
2个回答

5

以下是四种常见的注释级别。这些都可以编译而不出现错误:

// Truly general
const genFnA: Function = function* () {};

// Bit less general
const genFnB: () => Generator = function* () {};

// Exact manual
const genFnC: () => Generator<never, void, unknown> = function* () {};

// Best: Use the inference
const genFnD = function* () {};

3
这是一个非常奇怪的碰撞,将众所周知的符号和生成器添加到Typescript类型系统中。在符号的原始提案中,Anders Hejlsberg提出了以下建议
interface Object {
  [Symbol.toStringTag]: string;
}

这是一种非常合理的方法,使每个人都能在每个对象上设置Symbol.toStringTag,并且实际上这就是其旨在使用的方式。出于我无法重构的原因,这没有被添加到Object接口,甚至没有添加到Function接口中,而仅添加到GeneratorFunction接口中。因此,虽然它们实际上是等效的(都可以被调用),但函数不能分配给生成器函数。
第二个奇怪的事情是,function*表达式评估为() => Generator而不是GeneratorFunction。尽管应该假设它们是等效的,但由于缺少Symbol.toStringTag,它们并不相等。
因此,我们无法将function*分配给GeneratorFunction,尽管它们被认为(实际上是)描述了相同的类型,这使得GeneratorFunction接口几乎无用。
这可能是由于我没有注意到的各种限制,或者是Typescript类型中的一个错误导致的。

我投票是bug(漏洞)。即使这是由于实际限制,结果是接口并没有像应该的那样实际可用。因此,导致编译错误。 - VLAZ
1
@vlaz 我打开了一个问题 - Jonas Wilms
1
我已经提交了 - 我知道微软在考虑要修复什么问题时会关注这些。 - VLAZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接