Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't get iterator from iterable object #1163

Open
ikokostya opened this issue Dec 6, 2015 · 12 comments
Open

Can't get iterator from iterable object #1163

ikokostya opened this issue Dec 6, 2015 · 12 comments
Labels

Comments

@ikokostya
Copy link

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
@karelbilek
Copy link
Contributor

karelbilek commented Apr 27, 2016

+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.

@iamchenxin
Copy link
Contributor

iamchenxin commented Sep 4, 2016

Are there some process for this?
Is there some standard way to write iterator protocol in Flow?
Same error in 0.31

@reneloperena
Copy link

Getting the same error on 0.32

@drborges
Copy link

Any news on this?

@zacharygolba
Copy link
Contributor

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.

Example

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)
}

@dimpiax
Copy link

dimpiax commented Sep 19, 2017

Any status?

@aleclarson
Copy link

@karel-3d Your fix doesn't seem to work anymore.

Indexable signature not found in $Iterable

@olebedev
Copy link

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
    }
  }
}

@FDiskas
Copy link

FDiskas commented Feb 7, 2018

@Gozala
Copy link
Contributor

Gozala commented Feb 9, 2018

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
    }
  }
}

@Gozala
Copy link
Contributor

Gozala commented Feb 10, 2018

I have published iterable.flow package to npm to overcome this issue until it's properly fixed.

@lll000111
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests