繁体   English   中英

如何在接口中定义和实现生成器 function 和 class

[英]How to define and implement a generator function in an interface and class

在 »plain JS« 中,代码是这样的:

class Powers {
  *[Symbol.iterator]() {
    for(let i = 0; i < 10; i++) 
     yield { i, pow: Math.pow(i, i) }
    return null;
  }
}

然后可以这样使用:

const powers = [...new Powers()];

Typescript 接口如何定义它? 按照这里的文档,我是这样开始的:

interface PowGen {
  //where should the * go?
  [Symbol.iterator]: () => Generator<any, any, any>
}

像这样详尽地使用 »any« 解决了很多编译器错误,但也让我觉得我的代码有问题。 [Symbol.iterator]旁边, Iterator<>Generator<>接口列出了nextreturnthrow方法。 我是否也必须实施它们?

class Powers implements PowGen {
  *[Symbol.iterator]():Generator<any, any, any> {
    for(let i = 0; i < 10; i++) 
      yield { i, pow: Math.pow(i, i) }
    return null;
  }
}

只是一个小例子或解释,这比文档真正有帮助的要冗长一些”。

问题本身已经部分给出了答案。

需要的接口是:

type YieldType = { type: 'yielded' };
type ReturnType = null;
type ReturnToNext = true | undefined;

interface Foo {
  [Symbol.iterator]: () => Generator<YieldType, ReturnType, ReturnToNext>
}

和实施:

class Bar implements Foo {
  *[Symbol.iterator] () : Generator<YieldType, ReturnType, ReturnToNext> {
    const 
      items = [ { type: 'yielded' }, … ], // this is a really long list
      n = items.length
    ; 

    let 
      i = 0, 
      stop = undefined
    ;

    while (i < n && && stop === undefined) {
      stop = yield items[i];     
      i++;
    }

    return null;
  }
}

由于ReturnToNext的类型接受undefined ,因此也可以在 Foo 的实例上使用扩展运算符。 所以:

let 
  foo = new Foo(),
  first = foo[Symbol.iterator]().next(true).value // stops the generator
;

或者

let items = [...new Foo()];

是可能的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM