Ce face iteratori cu tipuri
for...of, operatorul ..., Array.from și destructurarea funcționează cu orice obiect iterabil: un obiect care are metoda [Symbol.iterator](). Metoda returnează un iterator, un obiect cu metoda next() care dă pe rând { value, done }. Tablourile, textele, Map și Set sunt deja iterabile.
TypeScript descrie aceste roluri cu interfețele Iterable<T>, Iterator<T> și IterableIterator<T> (ambele deodată). O clasă proprie devine iterabilă dacă implementează [Symbol.iterator]; cel mai simplu este să scrii metoda ca generator (*[Symbol.iterator]()).
Un parametru de tip Iterable<T> acceptă tablouri, Set-uri, generatori și clase proprii, deci face funcția mai generală decât T[]. Din ES2025, iteratorii predefiniți au și metode ca map, filter, take (tipul IteratorObject), explicate în secțiunea JavaScript.
Exemple
Exemplul 1: Clasă iterabilă scrisă cu generator
class Clasa implements Iterable<string> {
#elevi: string[] = [];
adauga(...nume: string[]): this {
this.#elevi.push(...nume);
return this;
}
*[Symbol.iterator](): Generator<string> {
yield* this.#elevi.toSorted((a, b) => a.localeCompare(b, "ro"));
}
}
const c = new Clasa().adauga("Mihai", "Ana", "Ștefan", "Ioana");
for (const elev of c) console.log(elev);
console.log([...c].length, Array.from(c).at(-1));
Rezultat
Ana
Ioana
Mihai
Ștefan
4 Ștefan
Exemplul 2: Iterator scris de mână
Obiectul returnat de next() are tipul IteratorResult<number>.
class Interval implements Iterable<number> {
constructor(private start: number, private stop: number, private pas = 1) {}
[Symbol.iterator](): Iterator<number> {
let curent = this.start;
const { stop, pas } = this;
return {
next(): IteratorResult<number> {
if (curent > stop) return { done: true, value: undefined };
const value = curent;
curent += pas;
return { done: false, value };
},
};
}
}
console.log([...new Interval(1, 10, 3)]);
let suma = 0;
for (const n of new Interval(1, 100)) suma += n;
console.log(suma);
Rezultat
[ 1, 4, 7, 10 ]
5050
Exemplul 3: Funcție care acceptă orice iterabil
function total(valori: Iterable<number>): number {
let s = 0;
for (const v of valori) s += v;
return s;
}
const preturi = new Map([["pâine", 5], ["lapte", 7.5]]);
console.log(total([1, 2, 3]), total(new Set([10, 10, 20])), total(preturi.values()));
Rezultat
6 30 12.5
Greșeli frecvente
- Parcurgi cu
for...ofun obiect simplu ({ a: 1 }). tsc dă Type ‘{ a: number; }’ must have a ‘[Symbol.iterator]()’ method that returns an iterator; foloseșteObject.entries. - Confunzi
for...in(cheile unui obiect, ca texte) cufor...of(valorile unui iterabil).
Comenzi înrudite
generatori cu tipuri: Funcțiile function* produc valori una câte una cu yield; tipul lor este Generator<T, TReturn, TNext>.bigint și symbol: bigint ține numere întregi oricât de mari; symbol este o valoare unică, folosită de obicei drept cheie de proprietate.implements: O clasă promite că respectă una sau mai multe interfețe; tsc verifică dacă are toți membrii ceruți.array (T[] și Array<T>): Tipul tablourilor: T[] și Array<T> înseamnă același lucru, un tablou cu elemente de tipul T.