Menu

TypeScript Enum: Sayısal, String ve const Enum'lar

TypeScript enum, enum Direction { Up, Down } gibi adlandırılmış bir sabitler kümesidir. Sayısal ve string enum'ları, bir enum'ın derlendiği JavaScript'i, reverse mapping'i, bir enum üzerinde dolaşmayı, const enum'ları ve string literal union'ının ya da as const nesnesinin ne zaman daha iyi olduğunu öğrenin.

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

Bir TypeScript enum'ı, adlandırılmış bir sabitler kümesidir. enum Direction { Up, Down, Left, Right } hem Direction adında bir tip hem de üyelerine Direction.Up şeklinde eriştiğiniz bir çalışma zamanı nesnesi oluşturur. Üyelere değer vermezseniz 0'dan başlayarak numaralandırılır; string enum'lar ise her üyeye okunabilir bir string verir.

Enum'lar, yalnızca tip olmayan az sayıdaki TypeScript özelliğinden biridir: kod derlendiğinde bir enum gerçek bir JavaScript nesnesine dönüşür.

Sayısal Enum'lar

Başlangıç değeri verilmezse üyeler 0, 1, 2 gibi değerler alır. İlk üyeye bir sayı verin, geri kalanlar ondan devam eder. Her değeri açıkça da belirleyebilirsiniz; sayılar bir veritabanında saklanıyor ya da ağ üzerinden gönderiliyorsa güvenli seçim budur.

Otomatik numaralandırmaya güvenmek programdan hiç çıkmayan değerler için sorun değildir. Üyelerin sırası değişebilecekse ve sayılar herhangi bir yerde saklanıyorsa, ortaya bir üye eklemek ondan sonraki her şeyi sessizce yeniden numaralandırır.

Bir Enum Neye Derlenir

Tipler silinir, ama bir enum silinmez. TypeScript'in sayısal ve string bir enum için ürettiği JavaScript şudur:

enum Direction { Up, Down, Left, Right }
enum Status { Active = "ACTIVE", Inactive = "INACTIVE" }
var Direction;
(function (Direction) {
    Direction[Direction["Up"] = 0] = "Up";
    Direction[Direction["Down"] = 1] = "Down";
    Direction[Direction["Left"] = 2] = "Left";
    Direction[Direction["Right"] = 3] = "Right";
})(Direction || (Direction = {}));
var Status;
(function (Status) {
    Status["Active"] = "ACTIVE";
    Status["Inactive"] = "INACTIVE";
})(Status || (Status = {}));

Direction["Up"] = 0 ifadesi 0 döndürür, bu yüzden Direction[0] = "Up" aynı ifadede ayarlanır. Böylece sayısal bir enum iki yönlü eşleme yapar: addan sayıya ve sayıdan tekrar ada. Buna reverse mapping denir. String enum'lar yalnızca adları değerlere eşler.

Yazdırılan Direction nesnesinin sekiz anahtarı vardır: dört ad ve dört sayı. Bu, üzerinde dolaşmaya başladığınız anda önem kazanır.

String Enum'lar

Bir string enum'ın her üyesi açık bir string değeri ister. Değerler loglarda, JSON'da ve veritabanlarında olduğu gibi görünür; bu da string enum'larda hata ayıklamayı sayılara göre kolaylaştırır.

Bir string enum, insanları şaşırtan bir açıdan nominaldir: metin bir üyenin değeriyle eşleşse bile düz bir string ona atanamaz.

index.ts(7,5): error TS2820: Type '"ACTIVE"' is not assignable to type 'Status'. Did you mean 'Status.Inactive'?

(Mesajdaki öneri derleyicinin bir tahminidir ve burada yanlıştır; çözüm Status.Active yazmaktır.) Diğer yönde, bir Status değeri string beklenen her yerde kullanılabilir. Değerler JSON'dan veya bir formdan string olarak geldiğinde, onları aşağıdaki değer kontrolü bölümündekine benzer bir kontrolle dönüştürün.

Bir Enum'ı Tip Olarak Kullanmak

Enum adı, değerleri üyeleri olan bir tiptir. switch ile birleştiğinde, fonksiyonun bir değer döndürmesi gerektiğinde TypeScript her üyenin ele alındığını kontrol eder:

Shape tipine yeni bir case olmadan yeni bir üye eklenirse sides fonksiyonu TS2366 ile derlenmez olur: Function lacks ending return statement and return type does not include 'undefined'. Daha katı, never tabanlı kapsamlı kontrolü switch sayfası gösteriyor.

Son satırlar sayısal enum'ların gerçek bir zayıflığını gösteriyor. Hiçbir üyeyle eşleşmeyen bir sayı literal'i, const level: Level = 99, bir derleme hatasıdır (TS2322), ama number tipindeki her değer kabul edilir; bu yüzden 57 geçip gider. String enum'larda bu açık yoktur.

Bir Enum Üzerinde Dolaşmak

Bir enum çalışma zamanında bir nesnedir, bu yüzden Object.keys, Object.values ve Object.entries çalışır. Bir string enum için tam olarak üyeleri döndürürler. Sayısal bir enum için reverse mapping girdilerini de döndürürler, onları filtrelersiniz:

Bir değişkene "enum'ın üye adlarından biri" tipini vermek için "Up" | "Down" | "Left" | "Right" union'ına karşılık gelen keyof typeof Direction kullanın. Ardından Direction[name] değeri tam tip güvenliğiyle bulur.

Bir string enum'da reverse mapping yoktur; bu yüzden bir üyenin adını değerinden bulmak için girdilerde arayın: Object.entries(Status).find(([, v]) => v === "ACTIVE")?.[0] sonucu "Active" olur, hiçbir üye o değere sahip değilse undefined.

Bir Değerin Enum'da Olup Olmadığını Kontrol Etmek

Program dışından gelen veriler düz bir string veya number değeridir. Bir type guard onu enum'ın değerlerine karşı kontrol eder ve enum tipine daraltır:

Güvenilmeyen girdide raw as Status kullanmaktan kaçının: assertion derlenir ama çalışma zamanında hiçbir şey kontrol edilmez; böylece "DELETED" programın içinde geçerli bir Status olarak tiplenmiş halde dolaşır.

const Enum'lar

const enum, derleyiciden enum'ı silmesini ve her üyenin değerini kullanıldığı yere yazmasını ister. Çalışma zamanında bir nesne yoktur, bu yüzden hiçbir şey üzerinde dolaşılamaz ve reverse mapping yapılamaz.

const enum birkaç bayt ve bir özellik aramasından tasarruf sağlar, ama derleyicinin onu kullanan her dosyayı derlerken enum'ın bildirimini görmesine bağlıdır. Babel ve swc gibi dosyaları tek tek dönüştüren araçlar başka bir dosyada bildirilmiş bir const enum'ı göremez; Node'un type stripping özelliği const enum'ları diğer her enum gibi reddeder; isolatedModules veya verbatimModuleSyntax açıkken de bir bildirim dosyasındaki const enum'ı kullandığınızda TypeScript TS2748 hatası bildirir. Çoğu uygulama kodunun const enum'lara ihtiyacı yoktur.

Enum, Union Tip ve as const Nesnesi

Sabit bir değer kümesini tanımlamanın yaygın üç yolu vardır:

enumLiteral union'ıas const nesnesi
Çalışma zamanında varevet, bir nesnehayırevet, düz bir nesne
Değerler üzerinde dolaşmaObject.values (sayısal: filtreleyin)hayır, dolaşılacak bir şey yokObject.values
Düz bir "red" kabul ederhayır (string enum'lar)evetevet
X.Red ile adla erişimevethayırevet
Reverse mappingyalnızca sayısal enum'larhayırhayır
Node type stripping ile çalışırhayırevetevet
erasableSyntaxOnly izin verirhayırevetevet
Öğrenilecek ek sözdizimienum kuralları, const enum'laryoktypeof kalıbı

Pek çok ekip artık varsayılan olarak bir string literal union'ı kullanıyor, değerlere çalışma zamanında ihtiyaç duyduğunda da (üzerlerinde dolaşmak ya da bir açılır liste oluşturmak için) as const nesnesine geçiyor. Nedenleri: union'lar saf tiplerdir ve çıktıdan kaybolur; JSON ve API'lerin getirdiği düz string'leri kabul ederler; enum'lar da günlük TypeScript'in "JavaScript artı silinebilir tipler" olmayan tek parçasıdır.

Bu son nokta artık pratik bir önem taşıyor. Node, .ts dosyalarını tipleri silerek doğrudan çalıştırır ve bir enum silebileceği bir şey değildir:

node status.ts
SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode

Node'un --experimental-transform-types bayrağı enum'ların çalışmasını sağlar; erasableSyntaxOnly derleyici seçeneği ise her enum'ı TS1294 hatası olarak bildirir, This syntax is not allowed when 'erasableSyntaxOnly' is enabled.; böylece bir proje onları baştan yasaklayabilir. Type stripping'in nasıl çalıştığı için TypeScript çalıştırma sayfasına bakın. Bunların hiçbiri enum'ları yanlış yapmaz: tsc veya bir bundler ile derlenen kod onları sorunsuz çalıştırır ve enum'ları zaten kullanan bir kod tabanı onları dönüştürmekten pek bir şey kazanmaz.

Sıkça Sorulan Sorular

TypeScript'te enum nedir?

Hem bir tip hem de bir çalışma zamanı nesnesi olan adlandırılmış bir sabitler kümesidir: enum Direction { Up, Down }, Direction.Up yazmanıza ve Direction tipini bir parametre tipi olarak kullanmanıza izin verir. TypeScript özelliklerinin çoğunun aksine bir enum silinmez: çalışma zamanında var olan bir JavaScript nesnesine derlenir.

TypeScript'te bir enum üzerinde nasıl dolaşılır?

Bir string enum için Object.values(MyEnum) değerleri, Object.keys(MyEnum) adları verir. Sayısal bir enum reverse mapping girdileri de içerir ("0": "Up"), bu yüzden onları filtreleyin: Object.keys(Direction).filter((k) => isNaN(Number(k))) yalnızca adları verir. Bir const enum üzerinde dolaşılamaz, çünkü çalışma zamanında var değildir.

TypeScript'te bir string'i enum değerine nasıl çeviririm?

String'i bir type guard içinde enum'ın değerlerine karşı kontrol edin: function isStatus(s: string): s is Status { return (Object.values(Status) as string[]).includes(s); }. Kontrolden sonra s değişkeninin tipi Status olur. Düz bir s as Status derlenir ama çalışma zamanında hiçbir kontrol yapmaz.

TypeScript'te enum mu, union tip mi kullanmalıyım?

Pek çok ekip bir string literal union'ını (type Status = "active" | "inactive"), değerlere çalışma zamanında da ihtiyaç duyduklarında bir as const nesnesini tercih ediyor. Union'lar tamamen silinir, Node'un yerleşik type stripping özelliği ve erasableSyntaxOnly seçeneğiyle çalışır ve "active" gibi düz string'leri kabul eder. Enum'lar da gayet iyidir, özellikle onları zaten kullanan kod tabanlarında.

enum ile const enum arasındaki fark nedir?

Normal bir enum, çalışma zamanında üzerinde dolaşıp arama yapabileceğiniz bir nesneye derlenir. Bir const enum derleme sırasında silinir ve her kullanımı değeriyle değiştirilir (Size.Large ifadesi 2 olur); böylece çalışma zamanında hiçbir maliyeti olmaz ama üzerinde dolaşılamaz ve dosyaları tek tek derleyen araçlar onu kısıtlar.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA