为什么 TypeScript Iterable Iterator<> 和 Generator<> 泛型略有不同?

2024-02-15

在 TypeScript 中 (3.6.3)发电机几乎与可迭代迭代器. When 发电机延伸迭代器,它默认第三个通用参数(TNext) to unknown. 迭代器本身默认TNext to 不明确的. So 发电机 and Iterator (and 可迭代迭代器)没有像他们应该的那样排队。

let gen2:IterableIterator<string>;

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

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

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


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

他们为什么要添加它们?

(in 这次提交 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。接下来是介绍 https://github.com/microsoft/TypeScript/pull/30790 to:

[…]正确检查结果并提供类型yield基于生成器返回类型注释的下一个类型的表达式(即TNext输入Generator定义如上)。

为什么是默认值?

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

我们必须注意,在使用中存在惯用差异next()生成器和非生成器迭代器中的函数。作为ECMA-262 备注 https://tc39.es/ecma262/#sec-iterator-interface对于迭代器。

参数可以传递给next函数,但它们的解释和有效性取决于目标迭代器。 for-of 语句和迭代器的其他常见用户不传递任何参数,因此希望以这种方式使用的迭代器对象必须准备好处理不带参数的调用。

迭代器主要用在 for-of 循​​环中,不向 next 传递参数。事实上,将参数传递给下一个函数的情况非常罕见(MDN 甚至称其为“零参数函数”)。因此,默认值的唯一明智选择TNext将会undefined。进行中unknown将是类型检查的一个很大的障碍(更不用说用--strictNullChecks).

如果将一个参数传递给next()带有生成器的函数并不是一种很常见的做法 - 它实际上有一个有效的用例......并且定义了行为标准 https://tc39.es/ecma262/#sec-generator.prototype.next:

生成器.prototype.next(value)

The next方法执行以下步骤:

  1. Let g be the this value.
  2. 返回?GeneratorResume(g, value, 空的)。

and in MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next:

要发送到生成器的值。

该值将被分配为yield表达。例如,在variable = yield expression,传递给的值.next()函数将被分配给variable.

更不用说,在典型的用例中,第一个.next()call 将在没有参数的情况下调用,后续的调用将带有参数。不幸的是,没有办法指定“可选的第一次,未知的后续时间”类型,所以我想鉴于这一切,他们解决了unknown为了TNext在发电机中。

当然,没有完美的情况。但他们必须满足于他们认为问题最少的做法。

所有这些问题都在这个问题 https://github.com/Microsoft/TypeScript/issues/2983对于任何有兴趣的人。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 TypeScript Iterable Iterator<> 和 Generator<> 泛型略有不同? 的相关文章

随机推荐

  • Android AVD - AVD 的模拟器进程已终止

    我在 StackOverflow 上进行了搜索 发现了许多类似的问题和许多不同的答案 但没有一个对我有用 所以 最后几天我一直很好地使用 Android Studio 的模拟器 直到我尝试添加一个新的虚拟设备谷歌播放API 当我尝试运行它时
  • Visual Studio 中大型解决方案中最喜欢的项目

    如果有人问这个问题 我深表歉意 我找不到比赛 我有一个解决方案 96 个项目 我一次和 3 4 个人一起工作 有没有办法过滤掉 标记为收藏等我当前感兴趣的项目 由于项目是按字母顺序排序的 而且我的一个项目从 B 开始 另一个从 T 开始 所
  • 如何在浏览页面时在浏览器地址栏中添加图片?

    复制 网站 URL 旁边的图像图标 https stackoverflow com questions 120420 image icon beside the site url 当前让网站图标在所有支持网站图标的浏览器中显示的最佳方法是什
  • ASP.NET Core 存储过程无法在循环中工作

    我想使用存储过程进行数据库查询 它适用于单个查询 但在循环中 它像第一个循环迭代一样执行 var getAutoResults new List
  • 按位运算。该代码安全且可移植吗?

    我需要计算表示为的位集之间的汉明距离char数组 这是一个核心操作 因此必须尽可能快 我有这样的事情 const int N 32 32 always returns the number of bits that are ones in
  • 在 Java 中强制虚假唤醒

    这个问题不是关于虚假唤醒是否真的发生 因为这已经在这里进行了详细讨论 Java 中的虚假唤醒真的会发生吗 https stackoverflow com questions 1050592 do spurious wakeups actua
  • 使用定义的宽度、长度和像素位置裁剪视频文件

    我试图创建一个程序来检测视频中的脸部 在我接受 面子 之前 必须满足一些要求 满足所有要求后 我想要拍摄容纳该 脸部 的框架并裁剪它们以使脸部成为焦点区域 该程序将遍历每一帧并执行此操作 然后获取新视频并将其制作成视频文件 我从未使用过视频
  • 如何对包含特定单词的行进行列排序

    我只想对包含特定单词的行的特定列进行排序 我不想看到不包含该单词的行 例如我有这个文本文件 sdf ggfds 7 sdf sgs 5 sdf dfgs 3 foo dffg 2 bar dffg 2 sdf sddfg 4 我想对仅包含
  • 使用 Intl.DateTimeFormat 和 en-US 区域设置,Safari 中的日期显示相差一

    Safari 的 Int DateTimeFormat 实现似乎假定 3 月的第二个星期日始终是 DST 时间截止点 这是不正确的 因为在 2007 年之前它是 4 月的第一个星期日 当 DST 结束时 这似乎也会影响另一端 PS 此代码正
  • 为什么在大多数 ASP.NET MVP 实现中,Presenter 附加到 View 事件而不是 View 调用 Presenter 方法?

    我注意到在 Webforms MVP 实现和大多数其他示例中 Presenter 通常将处理程序附加到 View 事件 为什么视图不能直接调用演示者中的方法 只是想知道 由于将处理程序附加到事件 为特殊参数定义 EventArgs 在视图端
  • vagrant up 错误不起作用

    我尝试在我的计算机上安装 Laravel Homestead 我已经按照文档进行操作 昨天我就开始工作了 然而 我让笔记本电脑处于睡眠状态 并尝试运行 vagrant 配置 但收到了这个奇怪的错误 Jafars iMac Homestead
  • 无法从可执行共享库打印浮点数

    我正在开发一个共享库 它可以独立执行以打印它自己的版本号 我将自定义入口点定义为 const char my interp attribute section interp lib64 ld linux x86 64 so 2 void m
  • 将 Activiti 任务从旧流程迁移到新流程

    我有一个用于某些业务流程的 Activiti 项目 问题在于移民 现有流程有一些未完成的任务 我想通过添加新步骤来修改现有流程 现在 当我创建一个新任务时 这个新任务将根据更新的流程进行处理 而未完成的任务将按照旧流程进行处理 让我们看下面
  • IBM Watson Knowledge Studio - 注释负面/否定提及

    使用 Watson Knowledge Studio 注释提及内容时 通常会出现以下示例 我没有收到任何反馈 或 我从未收到任何反馈 如果我要注释上面提到的 反馈 那么它是一个 负面 例子 即它指的是没有发生的事情 创建自定义实体类型系统有
  • 如果对象成员没有值,如何为对象分配 null - automapper c#

    我在 C 中使用自动映射器 class A public int Value get set public string Code get set public B Details get set class B public int Id
  • 基于正则表达式的随机文本生成器[重复]

    这个问题在这里已经有答案了 我想知道是否有软件可以在给定正则表达式以及其他一些约束 例如长度 的情况下生成始终与给定正则表达式匹配的随机文本 谢谢 是的 可以生成与正则表达式随机匹配的软件 Exrex https github com as
  • sotimeout 在 android 2.1 上的多部分 http 帖子中不起作用

    我正在使用 android sdk 附带的 apache httpclient 使用多部分 http post 在服务器上上传文件 问题是 当我关闭设备上的 wifi 连接并且设置 sotimeout 和 connectiontimeout
  • 覆盖password_validation消息

    我使用 UserCreationForm 来创建新用户 from django contrib auth forms import UserCreationForm class RegistrationForm UserCreationFo
  • 在反应本机可触摸视图上启用触觉反馈

    我正在编写一个反应本机应用程序 我注意到虽然按钮在单击时看起来像本机按钮 但它们的行为并不像一个按钮 至少不像 Android 按钮的行为 单击 Android 应用程序按钮 发出声音并向用户提供触觉反馈 在声音中 我看到有 github
  • 为什么 TypeScript Iterable Iterator<> 和 Generator<> 泛型略有不同?

    在 TypeScript 中 3 6 3 发电机几乎与可迭代迭代器 When 发电机延伸迭代器 它默认第三个通用参数 TNext to unknown 迭代器本身默认TNext to 不明确的 So 发电机 and Iterator and