为什么TypeScript的IterableIterator <>和Generator <>泛型稍有不同?

时间:2019-10-26 05:47:05

标签: typescript iterator generator

在TypeScript(3.6.3)中, Generator <> IterableIterator <> 几乎相同。当 Generator <> 扩展 Iterator <> 时,它将默认的第三个通用参数(TNext)设置为 unknown 迭代器<> 本身默认将 TNext 设置为未定义。因此, Generator Iterator (以及 IterableIterator )的排列不尽如人意。

let gen2:IterableIterator<string>;

function* gen1():Generator<string> {
    yield* gen2;
}

yield *行是一个错误:“无法将迭代委派给值,因为其迭代器的'next'方法期望类型为'undefined',但是包含的生成器将始终发送'unknown'。ts(2766)”。< / p>

我想念什么吗?有充分的理由吗?

1 个答案:

答案 0 :(得分:6)

这实际上是一个非常复杂的问题。我不假装完全理解它。但是也许我可以提供一些见识。

为什么要添加它们?


(在此提交https://github.com/microsoft/TypeScript/commit/e8bf9584aa74aabfecb51a02edb13e3657508274#diff-5c3d60d8ed16d2857e28a35a61302b48中)。 Typescript决定好坏,都希望对生成器进行更严格的类型检查。实际上有一些正当的理由。请看下面的例子

function* foo() {
    let m = 0;

    while (m < 10) {
      yield m++;
    }

    return "done";
}

let gen = foo(),
    curr;

while(!(curr = gen.next()).done) {}

// At his point we should know that 
// curr.value is a string because curr.done is true

在这里我们可以看到问题-我们不知道是否应该通过所有逻辑规则返回或产生值。因此,他们推出了TReturn。 TNext被介绍给:

[...]正确检查a的结果并提供类型 基于生成器返回类型的下一种类型的yield表达式 注释(即上面的Generator定义中的TNext类型)。 https://github.com/microsoft/TypeScript/pull/30790

为什么使用默认值?


现在,如果您决定进行此类更改,则可能会破坏一些代码-目标是尽可能减少破坏。

我们必须注意,在生成器和非生成器迭代器中,next()函数的使用在习惯上有所不同。作为ECMA-262对迭代器的说明。

参数可以传递给下一个函数,但它们的解释 有效性取决于目标迭代器。的 语句和Iterators的其他普通用户不传递任何 参数,因此期望以这种方式使用的Iterator对象 必须准备好处理没有参数的调用。

迭代器主要用于for-of循环中,该循环不会将参数传递给next。实际上,很少将参数传递给下一个函数(MDN甚至将其称为“零参数函数”)。因此,TNext默认值的唯一明智的选择是undefined。使其成为unknown会大大阻碍类型检查(更不用说使用--strictNullChecks编译的代码了)。

如果不是很常见的做法是将参数与生成器一起传递给next()函数,那就太好了-它实际上具有有效的用例...并且在标准中定义了行为:

25.4.1.2 Generator.prototype.next(value)

下一个方法执行以下步骤:

让g为this值。 返回? GeneratorResume(g,value)。

和MDN

要发送到生成器的值。 该值将作为yield表达式的结果分配。例如,在in变量= yield表达式中,将值传递给 .next()函数将分配给变量。

更不用说,在典型的用例中,第一个.next()调用将在没有参数的情况下被调用,随后的调用将被带参数。不幸的是,没有办法指定“可选的第一次,以后的未知时间”这种类型,因此,我想根据他们为Generators中的TNext为unknown确定的所有条件。

当然,没有完美的情况。但是他们必须解决他们认为最没有问题的问题。

在本期https://github.com/Microsoft/TypeScript/issues/2983中讨论了所有这些问题,供有兴趣的人使用。