node.js - Ako zavolať Symbol.iterator rodičovskej triedy z vnútra Symbol.iterator podtriedy


Mám nasledujúce dve triedy v TypeScripte.

class BaseIter {
  constructor(public a: number, public b: number, public c: number, public d: number){}
  *[Symbol.iterator](): Iterator<number> {
    yield this.a
    yield this.b
    yield this.c
    yield this.d
  }
}

class MyIter extends BaseIter {
  get total() {
    return this.a + this.b + this.c + this.d
  }

  *[Symbol.iterator](): Iterator<number> {
    for(let x of this){
      yield x  
    }
    yield this.total
  }
}

const myIter = new MyIter(1, 2, 3, 4);

for (let n of myIter){
  console.log(n);
}

Trieda BaseIter prijíma štyri argumenty a pri iterovaní vracia tieto štyri argumenty späť. Mám podtriedu, ktorá rozširuje BaseIter a mala by používať funkciu iterácie rodiča, ale zároveň vracať aj ďalšiu hodnotu (celkovú sumu). Súčasný kód nefunguje - spôsobuje nekonečnú rekurziu (iterovanie cez this volá tú istú funkciu namiesto základnej funkcie). Skúšal som rôzne metódy super, ale bez úspechu.

Očakávam, že to vyprodukuje

1
2
3
4
10

Má niekto nejaké nápady?

Odpoveď č. 1

Generátorové funkcie majú návratový typ IterableIterator<T>, nie Iterator<T>. To bránilo TypeScriptu v tom, aby mohol metódu zo super triedy používať ako iterovateľnú. Vo všeobecnosti by ste mali nechať TypeScript odhadnúť návratovú hodnotu vašich funkcií, pokiaľ vás neupozorní, že to nie je možné.

class BaseIter {
  constructor(public a: number, public b: number, public c: number, public d: number) {}

  * [Symbol.iterator] () {
    yield this.a;
    yield this.b;
    yield this.c;
    yield this.d;
  }
}

class MyIter extends BaseIter {
  get total () {
    return this.a + this.b + this.c + this.d;
  }

  * [Symbol.iterator] () {
    yield * super[Symbol.iterator]();
    yield this.total;
  }
}

const myIter = new MyIter(1, 2, 3, 4);

for (const n of myIter) {
  console.log(n);
}