Menu

TypeScript Döngüler: for, forEach, for...of ve for...in

TypeScript'te döngü kurmanın tüm yolları ve her birinin size verdiği tipler: klasik for döngüsü, diziler, map'ler ve string'ler üzerinde for...of, for...in ve string anahtarları, forEach (break yok, await yok), nesne anahtarları üzerinde tipli döngüler ve while.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

TypeScript'te JavaScript'teki döngülerin aynısı vardır: for, for...of, for...in, while, do...while ve dizi metodu forEach. TypeScript'in eklediği şey tiplerdir: bir for...of döngüsünün değişkeni eleman tipine sahiptir ve bir for...in anahtarı her zaman string olur.

Dizi döngülerinin çoğunda ilk tercih for...of olmalıdır: kolay okunur, break, continue ve await destekler ve hiçbir tip notasyonu gerektirmez.

Klasik for Döngüsü

for (init; condition; update), saymak, birden fazla adım atlamak ya da geriye doğru ilerlemek için kullanılan döngüdür. TypeScript sayacın tipini başlangıç değerinden çıkarır.

Sayacı var ile değil let ile bildirin. let ile her iterasyon kendi bağlamasını alır, böylece döngüde oluşturulan bir callback o iterasyonun değerini görür.

for...of: Dizilerin, String'lerin ve Map'lerin Değerleri

for...of iterable olan her şey üzerinde çalışır ve döngü değişkeni karşılık gelen tipi alır. İndeksi de almak için [index, value] tuple'ları üreten array.entries() üzerinde döngü kurun.

break döngüden çıkar, continue ise bir sonraki elemana geçer; tıpkı bir for döngüsündeki gibi. Çalışma zamanı ayrıntıları (iterable'lar, generator'lar) JavaScript'in for...of ve for...in sayfasındadır.

forEach: break Yok, await Yok

forEach her eleman için bir fonksiyon çağırır ve undefined döndürür. Callback'in parametreleri diziden tiplenir, bu yüzden notasyon gerekmez. Yapamadığı iki şey vardır:

  • Erken durmak. Callback içindeki break bir derleme hatasıdır, TS1107: Jump target cannot cross function boundary. Bir return yalnızca o anki çağrıyı bitirir, yani continue gibi davranır.
  • Async işi beklemek. forEach, bir async callback'in döndürdüğü promise'i yok sayar.

Async tuzağını gözden kaçırmak kolaydır, çünkü hiçbir uyarı olmadan derlenir:

forEach callback'leri, döngü çoktan ilerledikten sonra timer sırasıyla (10, 20, 30) biter. for...of sürümü onları sırayla çalıştırır. Yine de beklediğiniz paralel iş için await Promise.all(items.map(async (item) => { ... })) kullanın.

for...in: Anahtarlar String'dir

for...in bir nesnenin sayılabilir özellik adları üzerinde döner. Anahtarın tipi her zaman string olur; anahtarların string olarak indeksler olduğu dizilerde bile. Bu da tipli bir nesneyi indekslemeyi zahmetli hâle getirir:

index.ts(5,22): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ name: string; age: number; }'.
  No index signature with a parameter of type 'string' was found on type '{ name: string; age: number; }'.

TypeScript anahtarı bilerek string olarak tipler: çalışma zamanında bir nesnenin tipinin listelediğinden daha fazla özelliği olabilir (yapısal tipleme fazladan özelliklere izin verir) ve for...in miras alınan sayılabilir özellikleri de dolaşır. Bu yüzden anahtarın "name" | "age" olduğunu garanti edemez. Çözümler bir sonraki bölümde. Dizilerde for...in kullanmaktan tamamen kaçının.

Bir Nesnenin Anahtarları ve Değerleri Üzerinde Döngü

Object.entries, [key, value] çiftleri verir ve bir nesne üzerinde döngü kurmanın olağan yoludur. Object.keys, for...in ile aynı sebepten string[] döndürür; bu yüzden nesnenin fazladan anahtarı olmadığını bildiğinizde anahtar tipi için assertion yapın.

Anahtarları önceden bilinmeyen veriler için nesneyi bir Record<string, number> olarak tipleyin ya da bir Map kullanın; ikisini de dictionary sayfası ele alır.

while ve do...while

while her geçişten önce koşulunu kontrol eder; do...while ise kontrol etmeden önce gövdeyi bir kez çalıştırır. Bir koşul sağlanana kadar okumak gibi, bir koleksiyonu dolaşmayan döngülere uygundur. İçlerinde daraltma çalışır: koşuldaki bir !== undefined kontrolünden sonra değişken gövdede daraltılmıştır.

İç İçe Döngülerde Label, break ve continue

Düz bir break yalnızca en içteki döngüden çıkar. Dıştaki bir döngüden çıkmak için ona bir label verin ve label'ın adını yazın:

Hangi Döngü Kullanılmalı

AmaçDöngü
Bir dizinin her elemanıfor (const x of arr)
Eleman ve indeksfor (const [i, x] of arr.entries()) ya da arr.forEach((x, i) => ...)
Erken durmakbreak ile for...of, ya da find, some, every
Her adımı await etmekiçinde await olan for...of
Yeni bir dizi oluşturmakmap, filter (döngü değil)
Saymak ya da n adım atlamakfor (let i = 0; ...; i += n)
Nesne anahtarları ve değerlerifor (const [k, v] of Object.entries(obj))
Map girdilerifor (const [k, v] of map)
Bir koşula kadarwhile

Sıkça Sorulan Sorular

TypeScript'te for döngüsü nasıl yazılır?

JavaScript'teki gibi: for (let i = 0; i < 5; i++) { ... }; TypeScript i değişkenini number olarak çıkarır. Bir dizinin elemanlarını dolaşmak için for (const item of items) daha kısadır ve item dizinin eleman tipini alır.

TypeScript'te forEach'ten nasıl çıkarım?

Çıkamazsınız: callback içindeki break bir derleme hatasıdır, TS1107 (Jump target cannot cross function boundary), ve return yalnızca o anki callback çağrısını bitirir, continue gibi davranır. break ile for...of kullanın ya da tasarım gereği erken duran some/find/every metotlarını kullanın.

TypeScript'te for...of ile for...in arasındaki fark nedir?

for...of bir iterable'ın değerlerini (dizi elemanları, string karakterleri, Map girdileri) gerçek tipleriyle dolaşır. for...in bir nesnenin sayılabilir özellik anahtarlarını dolaşır; bunlar her zaman string olarak tiplenir ve dizi indeksleri de string olarak gelir. Diziler için for...of, nesneler için Object.entries kullanın.

TypeScript'te bir nesnenin anahtarları ve değerleri üzerinde nasıl döngü kurarım?

for (const [key, value] of Object.entries(obj)) kullanın. key bir string, value ise özellik tiplerinin union'ıdır. key değişkeninin keyof typeof obj olarak tiplenmesi gerekiyorsa assertion yapın: (Object.keys(obj) as (keyof typeof obj)[]), çünkü TypeScript Object.keys sonucunu bilerek string[] olarak tipler.

forEach içinde await kullanılabilir mi?

Derlenir, ama forEach callback'in döndürdüğü promise'leri beklemez; bu yüzden döngü iş bitmeden sona erer. Sıralı iş için içinde await olan bir for...of kullanın, paralel çalıştırmak için de await Promise.all(items.map(async (x) => ...)) kullanın.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA