我使用的是typescript,并创建了以下代码
function* myIter(): Iterator<number> {
yield 3;
yield 2;
yield 1;
}
const iter: Iterator<number> = myIter();
const item:IteratorYieldResult<number> = iter.next();
字符串
演示
它会产生一个打字错误
的数据
在悬停时告诉我错误是什么
的
我检查了next
到底返回了什么,发现了这个接口定义:
interface Iterator<T, TReturn = any, TNext = undefined> {
// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
return?(value?: TReturn): IteratorResult<T, TReturn>;
throw?(e?: any): IteratorResult<T, TReturn>;
}
型
这就是我迷路的地方,因为我的迭代器被定义为Iteractor<number>
,所以TReturn
是什么。另一方面,它默认设置为any
,所以我猜它是可选的,我可以省略它。但由于某种原因,它不能以IteratorResult
的方式工作。无论如何,一些指导将不胜感激?
我不知道这里有什么问题,但也许有人能帮我解决这个问题?
2条答案
按热度按时间4urapxun1#
我不喜欢在每个调用点都检查
done
,因为我知道流应该包含多少元素,所以我写了一个小 Package 器来简化next()
的返回值:字符串
现在你可以做
型
它不是一个真正的“迭代器”,因为它没有实现交互器接口,所以你不能在
for
中使用它,但这不是我想要的方式(生成器已经支持for
,所以如果你想要的话直接使用它)vsaztqbk2#
如前所述,迭代器的
next()
方法返回IteratorResult
类型的值。定义如下:字符串
,
IteratorYieldResult
和IteratorReturnResult
的并集,它们本身定义如下:型
这意味着编译器告诉你
iter.next()
返回 * 要么 * 一个IteratorYieldResult
对象,带有false
/missingdone
属性,和一个number
类型的value
,* 要么 * 它返回一个IteratorReturnResult
对象,带有 *true
*done
属性,和一个any
类型的value
。你把它赋值给一个
IteratorYieldResult
类型的变量,编译器告诉你“等等,它可能不是这个类型,它可能是一个IteratorReturnResult
“。现在,因为你自己编写了生成器,你知道第一次调用
next()
你会得到一个IteratorYieldResult
,因为在函数返回之前有三个yield
语句。但这是类型系统没有的信息。就像这样:型
函数
foo()
根据它的类型签名返回number
或string
。你可以知道它总是返回string
,但是编译器不能告诉这一点,因为它只是查看签名,而不是深入实现。所以它抱怨:“嘿,也许str
在运行时将是number
,而不是你声称的string
”。那么在这里做什么才是“正确的”呢?我想这取决于你想做什么。在这个玩具例子中,你可以告诉编译器不需要担心,你肯定会得到一个
IteratorYieldResult
而不是IteratorReturnResult
。这种“告诉”编译器某个东西的类型比它可以验证的要窄的方式是通过类型Assert来完成的:型
或者,你可以做一般的检查,你 * 不 * 声称知道什么出来(这是有意义的,如果
myIter()
的实现可能会改变,或者如果你在循环中做iter.next()
):型
这里我们只是让编译器告诉我们
iter.next()
返回一个IteratorResult<number, any>
。然后我们通过检查done
属性来获取返回值并进行 * 测试 *。如果它不是true
,然后编译器会帮助你将结果缩小到IteratorYieldResult<number>
。你不需要Assert任何东西,因为编译器理解所做的类型检查以上;这是因为IteratorResult
是一个可区分的联合,其中可以检查单个属性(在本例中为done
)以确定您正在查看的是联合的哪个成员。好的,我希望这对你有意义和帮助。祝你好运!
Playground链接到代码