致谢
- 我承认使用此模板可能在维护者的酌情决定下被关闭,而无需进一步解释。
评论
#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();
6条答案
按热度按时间nx7onnlm1#
不幸的是,没有。尽管
BuiltinIterator
和BuiltinIteratorReturn
引用的 "Builtin" 有相似的命名,但它们实际上指的是两个不同的东西。BuiltinIterator
指的是原型链中具有全局Iterator.prototype
的任何Iterator
。这包括.values()
、.keys()
、.entries()
和[Symbol.iterator]()
在Array.prototype
、Map.prototype
、Set.prototype
、String.prototype
、DOMNodeLists
、类型数组、用户定义生成器以及全局Iterator
值的任何用户自定义子类(例如class MyIterator extends Iterator
)的结果。BuiltinIteratorReturn
仅指不是生成器且不是全局Iterator
值的用户自定义子类的内置迭代器的默认返回类型。由于
undefined
和void
之间的不兼容性,这是一个重要的区别。不会返回值的生成器通常会有一个与非生成函数保持一致的TReturn
,即void
。虽然通常认为void
本质上是undefined
,但实际上更像是“unknown
,但不要尝试使用该值”,因为函数类型可分配性的方式(即使unknown
不是可分配给void
的,但() => unknown
可以分配给() => void
)。在
BuiltinIterator
中将BuiltinIteratorReturn
作为TReturn
的默认值实际上导致了我们的用户测试中的许多中断。当我添加了
strictBuiltinIteratorReturn
选项和BuiltinIteratorReturn
时,它应用的方法仍然标记为IterableIterator
,我们仍在争论如何称呼代表迭代器助手提案引入的全局Iterator
值的接口。也许我们需要考虑重命名BuiltinIterator
以减少一些混乱,但我认为这不是解决您特定问题的方法,即使我们这样做了,我们仍然无法使其成为接口级别的默认值。然而,我考虑过的一个选项是删除
BuiltinIterator
中TReturn
类型的默认参数,这将表明您必须在那个位置放 something 而不是将其留空为any
。wgeznvg72#
感谢您的详细回复!
尽管如此,我仍然不明白的是,在TS 5.6中,将
BuiltinIteratorReturn
设置为TReturn
的默认值是如何导致破坏性的,因为BuiltinIterator
是TS 5.6中的新特性。现有的用户代码不应该依赖于默认的类型参数,尤其是当它只是默认值,而且对于那些只使用内置迭代器返回函数的人来说是不可观察的。我仍然担心上面提到的缺点。迭代器助手将使编写迭代器返回函数变得更加普遍,有些人,包括
isolatedDeclarations
用户,将希望明确写出BuiltinIterators
类型。就个人而言,删除默认选项感觉稍微好一些,因为有快速修复的方法可以帮助填补正确的类型的空缺。
cidc1ykv3#
或许还有另一种迭代器类型? 😅
$x_1a^0b^1x$
lzfw57am4#
请查看我上面的意见?我相信你漏掉了一些东西。我认为不可能通过设置一个新类型(
BuiltinIterator
)的默认类型参数来破坏用户测试。此外,虽然我理解"Builtin"在BuiltinIterator
和BuiltinIteratorReturn
中的区别,但实际上我觉得为后者中的"Builtin"迭代器创建另一个类型并不是一个坏主意。h79rfbju5#
@rbuckton,你能看一下我上面的意见吗?我相信你漏掉了一些东西。我认为设置一个新添加类型的默认类型参数是不可能破坏用户测试的(
BuiltinIterator
)。它可能不会破坏用户测试,但会破坏用户的直觉。通常,让类型参数的默认值与其约束匹配是一个好主意,尽管这不是一个要求。这是因为用户通常期望一个
BuiltinIterator<T, U>
可以分配给一个BuiltinIterator<T>
。此外,虽然我能理解 "Builtin" 在
BuiltinIterator
和BuiltinIteratorReturn
中的区别,但实际上我觉得为后一种意义上的 "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>
。我也可能要求
TReturn
和TNext
是IteratorObject
的必需项,尽管我预计有些人会觉得这很麻烦。yhqotfr86#
它可能不会破坏用户测试,但会破坏用户的直觉。
现在我理解了
BuiltinIteratorReturn
不能成为(当前)BuiltinIterator
的默认类型参数。我正在考虑重新排列名称并添加
IteratorObject
以表示从Iterator.prototype
继承的迭代器对象。好消息!这将解决我对显式写出迭代器类型的担忧。谢谢。