gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 02:42:25 25 4
gpt4 key购买 nike

在 TypeScript (3.6.3) 中,Generator<> 几乎与 IterableIterator<> 相同。当 Generator<> 扩展 Iterator<> 时,它默认第三个通用参数 (TNext) 为未知。 Iterator<> 本身默认 TNext 为未定义。所以生成器和迭代器(和 IterableIterator)并没有像它们应该的那样排列。

let gen2:IterableIterator<string>;

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

yield* 行是一个错误:“无法将迭代委托(delegate)给 value,因为其迭代器的 'next' 方法需要类型 'undefined',但包含的生成器将始终发送 'unknown'.ts(2766)”。

我错过了什么吗?这有充分的理由吗?

最佳答案

这实际上是一个非常复杂的问题。我并不假装完全理解它。但也许我可以提供一些见解。
他们为什么要添加它们?
(在 this commit 中)。
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 是 introduced到:

[…] correctly check, and provide a type for, the result of a yield expression based on the next type of the generator's return type annotation (i.e. the TNext type in the Generator definition above).


为什么是默认值?
现在,如果您决定进行此类更改,您可能会破坏一些代码 - 目标是尽可能少地破坏。
我们必须注意, next() 的使用存在惯用差异。生成器和非生成器迭代器中的函数。作为 ECMA-262 remarks对于迭代器。

Arguments may be passed to the next function but their interpretation and validity is dependent upon the target Iterator. The for-of statement and other common users of Iterators do not pass any arguments, so Iterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.


迭代器主要用于不将参数传递给 next 的 for-of 循​​环。实际上,将参数传递给下一个函数的情况很少见(MDN 甚至称其为“零参数函数”)。因此,默认值 TNext 的唯一明智选择将是 undefined .制作 unknown将是类型检查的一大障碍(更不用说用 --strictNullChecks 编译的代码)。
如果将参数传递给 next(),那就太好了。带有生成器的函数并不是很常见的做法——它实际上有一个有效的用例……并且在 the standard 中定义了行为:

Generator.prototype.next(value)

The next method performs the following steps:

  1. Let g be the this value.
  2. Return ?GeneratorResume(g, value, empty).

MDN :

The value to send to the generator.

The value will be assigned as a result of a yield expression. For example, in variable = yield expression, the value passed to the .next() function will be assigned to variable.


更不用说,在典型的用例中,第一个 .next() call 将在没有参数的情况下被调用,后续的将被调用。不幸的是,没有办法指定“第一次可选,后续时间未知”类型,所以我想鉴于这一切,他们选择了 unknown对于 TNext在发电机中。
当然,没有完美的情况。但他们必须满足于他们认为问题最少的事情。
所有这些问题都在 this issue 中讨论。对于任何有兴趣的人。

关于typescript - 为什么 TypeScript 的 IterableIterator<> 和 Generator<> 泛型略有不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58568399/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com