When I try to get iterator from iterable object using Symbol.iterator
/* @flow */
'use strict';
const a = [1, 2, 3];
for (const value of a[Symbol.iterator]()) {
console.log(value);
}
flow check produces error:
test.js:6
6: for (const value of a[Symbol.iterator]()) {
^^^^^^^^^^^^^^^^^^ access of computed property/element. Element cannot be accessed with
6: for (const value of a[Symbol.iterator]()) {
^^^^^^^^^^^^^^^ string
I have the same problem with Iterable interface:
/* @flow */
'use strict';
const iterable: Iterable<number> = [1, 2, 3];
const iter = iterable[Symbol.iterator];
$ flow check
test.js:6
6: const iter = iterable[Symbol.iterator];
^^^^^^^^^^^^^^^^^^^^^^^^^ access of computed property/element. Indexable signature not found in
6: const iter = iterable[Symbol.iterator];
^^^^^^^^ $Iterable
$ flow version
Flow, a static type checker for JavaScript, version 0.19.1
+1
This simple code does not work
function iterator<X>(x: Iterable<X>): Iterator<X> {
return x[Symbol.iterator];
}
There seems to be @@iterator() in flow/core.js but seems like a hack.
Are there some process for this?
Is there some standard way to write iterator protocol in Flow?
Same error in 0.31
Getting the same error on 0.32
Any news on this?
I think I found a half decent workaround that allows you to extract an iterator from an iterable object. It should work for any arbitrary Object type. This includes Map, Set, etc. One caveat is that you can't use the following utility functions to get an iterator from an array or string.
type IterFn<T: Object> = $PropertyType<T, '@@iterator'>
function extractIteratorFn<T: Object>(target: T): IterFn<T> {
return target[Symbol.iterator]
}
function isIterableObject(target: mixed): boolean %checks {
return (
target != null &&
typeof target === 'object' &&
typeof extractIteratorFn(target) === 'function'
)
}
function intoIterator<T: Object>(target: T): Iterator<*> {
return extractIteratorFn(target).call(target)
}
Any status?
@karel-3d Your fix doesn't seem to work anymore.
Indexable signature not found in $Iterable
FYI, this works(0.61) for me:
/* @flow */
export class Iter {
/*:: @@iterator(): Iterator<T> { return ({}: any); } */
// $FlowFixMe - computed property
[Symbol.iterator](): Iterator<T> {
return this;
}
next(): IteratorResult<T, void> {
return {
done: true
}
}
}
:pencil2: http://exploringjs.com/es6/ch_iteration.html#sec_overview-iteration
Anyone has any ideal why flow is unable to infer following code properly. It reports BreakingIterable Cannot extend IterableObject Property 'iterator' is incompatible but seems to work fine if iterator is annotated like it is in WorkingIterable definition.
class IterableObject<a> implements Iterable<a> {
+@@iterator: () => Iterator<a>
+iterator: () => Iterator<a>
}
Object.defineProperty(IterableObject.prototype, Symbol.iterator, {
value() {
return this.iterator()
}
})
class WorkingIterable<a> extends IterableObject<a> {
source: Set<a>
constructor(source: Set<a>) {
super()
this.source = source
}
*iterator(): Iterator<a> {
for (let item of this.source) {
yield item
}
}
}
class BreakingIterable<a> extends IterableObject<a> {
+source: Set<a>
constructor(source: Set<a>) {
super()
this.source = source
}
*iterator() {
for (let item of this.source) {
yield item
}
}
}
I have published iterable.flow package to npm to overcome this issue until it's properly fixed.
PING!
Flow 0.89, and when I add @@iterator(): Iterator<[K, V]>, to my object (not class) definition and in the object itself add a [Symbol.iterator] property Flow complains that there is no property called "@@iterator" in the object.
Most helpful comment
+1
This simple code does not work
There seems to be
@@iterator()in flow/core.js but seems like a hack.