Как определить и реализовать функцию генератора в интерфейсе и классе - PullRequest
0 голосов
/ 14 июля 2020

В «простом 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<> перечислены методы next, return и throw. Должен ли я их реализовать?

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

Просто небольшой пример или объяснение, которое немного более подробное, чем документы, которые действительно могут помочь ".

1 Ответ

0 голосов
/ 30 августа 2020

Ответ был частично уже дан в самом вопросе.

Необходимый интерфейс:

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

Поскольку тип of ReturnToNext принимает undefined, можно также использовать оператор распространения в экземпляре Foo. так что:

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

или

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

возможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...