如何实现Symbol.iterator?

Kyl*_*yle 6 javascript flowtype

我正在尝试创建Set的子类,因为我不能简单地从它扩展,我正在包装它的功能.

我正在尝试实现Symbol.iterator方法,但Flow没有.

这是我的代码:

/* @flow */
class CSet<T> {
    _set: Set<T>;
    [Symbol.iterator](): Iterator<T> {
        return this._set[Symbol.iterator];
    }
}

var a: CSet = new CSet();
for(var b of a){

}

core.js:309:5,29: property @@iterator
Property not found in
test.js:2:7,10: CSet

test.js:4:2,6:2: 
computed property keys not supported
Run Code Online (Sandbox Code Playgroud)

第二个错误不是很大的交易,因为我可以很容易地压制它.我想知道我是不是一起做错了.

小智 5

因为Flow目前没有对符号的一般支持,它所表示的方式Symbol.iterator是hacky并且基本上阻止了在用户空间中定义迭代器的能力(它的支持仅适用于库定义):(

特别是Flow期望一个iterable上有一个@@iterator属性(当然不是一个有效的属性名称 - 但这是获得库定义支持的临时黑客).

因此,在获得正确的符号支持之前,最好的解决方法是为此模块创建一个库定义,使用此@@iterator属性进行Flow的理解:

// RealModule.js
export class CSet {
    [Symbol.iterator]() {
        return this._set[Symbol.iterator];
    }
}
Run Code Online (Sandbox Code Playgroud)

.

// RealModule.FlowLibDef.js
declare module RealModule {
    declare class CSet<T> {
        _set: Set<T>;
        @@iterator(): Iterator<T>;
    }
}
Run Code Online (Sandbox Code Playgroud)


ckk*_*ght 5

// @flow
class MyCollection<T> {
    /*:: @@iterator(): Iterator<T> { return ({}: any); } */

    // $FlowFixMe: computed property
    [Symbol.iterator](): Iterator<T> {
        // NOTE: this could just as easily return a different implementation
        return new MyIterator(this);
    }
}

class MyIterator<+T> {
    /*:: @@iterator(): Iterator<T> { return (this: any); } */

    // $FlowFixMe: computed property
    [Symbol.iterator](): Iterator<T> {
        return this;
    }

    next(): IteratorResult<T, void> {
        return { done: false, value: someT };
        // or return { done: true, value: undefined };
    }
}

for (const value of new MyCollection()) {
    console.log(value);
}
Run Code Online (Sandbox Code Playgroud)

这样做的原因是流将/*:: code */其解释为源中的流代码,只是它在运行时被注释掉,因此实际上不会影响代码。

Flow 本质上知道该@@iterator方法,尽管它不是有效的 JavaScript,因此我们将其定义为存在,返回Iterator<T>,并返回一个适用于它的值(即一个空对象转换为any)。

然后计算属性方法被流完全忽略,就好像它根本没有定义一样。Iterator<T>从方法中实际返回一个有效值是至关重要的,否则事情会在运行时中断。