TypeScript TS 5.6 Beta内置迭代器返回值:这是否可以成为内置迭代器TReturn的默认类型参数?

vuv7lop3  于 5个月前  发布在  TypeScript
关注(0)|答案(6)|浏览(50)

致谢

  • 我承认使用此模板可能在维护者的酌情决定下被关闭,而无需进一步解释。

评论

#58243 引入了 BuiltinIteratorReturn 类型,并将其应用于所有类型定义中。
然后 #58222 引入了 BuiltinIterator 类型,并用 BuiltinIterator 替换了一些 IterableIterator 的使用。
我在想 BuiltinIteratorReturn 是否可以设置为 BuiltinIterator 类型的 TReturn 参数的默认类型参数,例如:

// lib.es2015.iterable.d.ts
interface BuiltinIterator<T, TReturn = BuiltinIteratorReturn, TNext = any> extends Iterator<T, TReturn, TNext> {
    [Symbol.iterator](): BuiltinIterator<T, TReturn, TNext>;
}

#58463 提到 BuiltinIteratorReturn 不能用于 IterableIterator ,因为 IterableIterator 不仅适用于内置迭代器,而且是通用类型。然而,这并不适用于 BuiltinIterator 。我认为我们可以安全地专门将 BuiltinIteratorReturn 用于 BuiltinIterator 的默认类型参数。
当前方法(在所有地方指定 BuiltinIteratorReturn)的缺点是,手动使用 BuiltinIterator 类型很容易禁用新编译器选项的好处:

const nums = new Set([1, 2, 3, 4, 5]);

// oops! This is BuiltinIterator<number, any, any> regardless of compiler option
const values: BuiltinIterator<number> = nums.values();
nx7onnlm

nx7onnlm1#

不幸的是,没有。尽管 BuiltinIteratorBuiltinIteratorReturn 引用的 "Builtin" 有相似的命名,但它们实际上指的是两个不同的东西。
BuiltinIterator 指的是原型链中具有全局 Iterator.prototype 的任何 Iterator。这包括 .values().keys().entries()[Symbol.iterator]()Array.prototypeMap.prototypeSet.prototypeString.prototype、DOM NodeLists、类型数组、用户定义生成器以及全局 Iterator 值的任何用户自定义子类(例如 class MyIterator extends Iterator)的结果。
BuiltinIteratorReturn 仅指不是生成器且不是全局 Iterator 值的用户自定义子类的内置迭代器的默认返回类型。
由于 undefinedvoid 之间的不兼容性,这是一个重要的区别。不会返回值的生成器通常会有一个与非生成函数保持一致的 TReturn,即 void。虽然通常认为 void 本质上是 undefined,但实际上更像是“ unknown,但不要尝试使用该值”,因为函数类型可分配性的方式(即使 unknown 不是可分配给 void 的,但 () => unknown 可以分配给 () => void)。
BuiltinIterator 中将 BuiltinIteratorReturn 作为 TReturn 的默认值实际上导致了我们的用户测试中的许多中断。
当我添加了 strictBuiltinIteratorReturn 选项和 BuiltinIteratorReturn 时,它应用的方法仍然标记为 IterableIterator,我们仍在争论如何称呼代表迭代器助手提案引入的全局 Iterator 值的接口。也许我们需要考虑重命名 BuiltinIterator 以减少一些混乱,但我认为这不是解决您特定问题的方法,即使我们这样做了,我们仍然无法使其成为接口级别的默认值。
然而,我考虑过的一个选项是删除 BuiltinIteratorTReturn 类型的默认参数,这将表明您必须在那个位置放 something 而不是将其留空为 any

wgeznvg7

wgeznvg72#

感谢您的详细回复!

尽管如此,我仍然不明白的是,在TS 5.6中,将BuiltinIteratorReturn设置为TReturn的默认值是如何导致破坏性的,因为BuiltinIterator是TS 5.6中的新特性。现有的用户代码不应该依赖于默认的类型参数,尤其是当它只是默认值,而且对于那些只使用内置迭代器返回函数的人来说是不可观察的。

我仍然担心上面提到的缺点。迭代器助手将使编写迭代器返回函数变得更加普遍,有些人,包括isolatedDeclarations用户,将希望明确写出BuiltinIterators类型。
就个人而言,删除默认选项感觉稍微好一些,因为有快速修复的方法可以帮助填补正确的类型的空缺。

cidc1ykv

cidc1ykv3#

或许还有另一种迭代器类型? 😅

$x_1a^0b^1x$

lzfw57am

lzfw57am4#

请查看我上面的意见?我相信你漏掉了一些东西。我认为不可能通过设置一个新类型(BuiltinIterator)的默认类型参数来破坏用户测试。此外,虽然我理解"Builtin"在BuiltinIteratorBuiltinIteratorReturn中的区别,但实际上我觉得为后者中的"Builtin"迭代器创建另一个类型并不是一个坏主意。

h79rfbju

h79rfbju5#

@rbuckton,你能看一下我上面的意见吗?我相信你漏掉了一些东西。我认为设置一个新添加类型的默认类型参数是不可能破坏用户测试的(BuiltinIterator)。
它可能不会破坏用户测试,但会破坏用户的直觉。通常,让类型参数的默认值与其约束匹配是一个好主意,尽管这不是一个要求。这是因为用户通常期望一个 BuiltinIterator<T, U> 可以分配给一个 BuiltinIterator<T>
此外,虽然我能理解 "Builtin" 在 BuiltinIteratorBuiltinIteratorReturn 中的区别,但实际上我觉得为后一种意义上的 "Builtin" 迭代器创建另一个类型并不是一个坏主意。
我正在考虑重新安排名称并添加 IteratorObject 以表示从 Iterator.prototype 继承的迭代器对象,如下所示:

  • IteratorObject<T, TReturn, TNext> 具有所有的迭代器帮助程序(即,目前被称为 BuiltinIterator 的内容)。
  • Generator<T, TReturn, TNext> extends IteratorObject<T, TReturn, TNext>
  • BuiltinIterator<T> extends IteratorObject<T, BuiltinIteratorReturn, unknown>
  • 所有内置都继承自 BuiltinIterator<T>

我也可能要求 TReturnTNextIteratorObject 的必需项,尽管我预计有些人会觉得这很麻烦。

yhqotfr8

yhqotfr86#

它可能不会破坏用户测试,但会破坏用户的直觉。
现在我理解了 BuiltinIteratorReturn 不能成为(当前) BuiltinIterator 的默认类型参数。
我正在考虑重新排列名称并添加 IteratorObject 以表示从 Iterator.prototype 继承的迭代器对象。
好消息!这将解决我对显式写出迭代器类型的担忧。谢谢。

相关问题