Salvo

WFN Üye
Konular
1,725
Mesajlar
1,747
Çözüm
0
Ticaret Puanı
0
Üyelik
6 Ay 16 Gün
Konum
İstanbul
Web Sitesi
Yok
Alanı
Belirtmemiş
1/1
Konu sahibi
İki-üç sabit değeri yalnızca TypeScript içinde kullanıyor, bu değerleri çalışma zamanında JavaScript nesnesi olarak okumuyor ve dışarıya ortak bir API sunmuyorsanız union type genellikle enum yerine daha uygun seçimdir. Union type, değişkenin alabileceği değerleri tip düzeyinde sınırlar; çalışma zamanında ek JavaScript kodu üretmez. Buna karşılık değerlerin çalışma zamanında da mevcut olması, tek bir ad alanı altında toplanması veya JavaScript tarafından okunacak bir nesneye ihtiyaç duyulması enum kullanımını anlamlı kılar.

Seçimi yaparken yalnızca yazım biçimine değil, şu soruya bakın: Bu değerler sadece derleyicinin kontrol edeceği bir küme mi, yoksa program çalışırken gerçekten erişilecek bir veri mi? İlk durumda union type, ikinci durumda enum ya da açıkça tanımlanmış sabit bir nesne daha uygun olabilir.

Union type ve enum arasındaki temel fark​


Union type, bir değişkenin yalnızca belirli değerlerden birini alabileceğini belirtir. Örneğin sipariş durumlarını şöyle tanımlayabilirsiniz:

Kod:
type OrderStatus = "pending" | "paid" | "shipped" | "cancelled";

function updateStatus(status: OrderStatus) {
  console.log(status);
}

updateStatus("paid");
// updateStatus("completed"); // Hata: "completed" izin verilen değerlerden biri değil

Burada OrderStatus yalnızca derleme aşamasında kullanılır. TypeScript kodu JavaScript'e dönüştürüldüğünde OrderStatus adında bir nesne oluşmaz. Bu nedenle çalışma zamanında OrderStatus değerlerini dolaşamaz veya bu ada erişemezsiniz.

enum ise bir çalışma zamanı yapısıdır. Üye adları ve değerleri JavaScript çıktısında da bulunur:

Kod:
enum OrderStatus {
  Pending = "pending",
  Paid = "paid",
  Shipped = "shipped",
  Cancelled = "cancelled"
}

function updateStatus(status: OrderStatus) {
  console.log(status);
}

updateStatus(OrderStatus.Paid);

Bu kullanımda OrderStatus.Paid çalışma zamanında erişilebilen bir değerdir. Dolayısıyla enum yalnızca tip denetimi sağlamaz; aynı zamanda JavaScript tarafında kullanılacak bir değer kümesi oluşturur.
ÖlçütUnion typeenum
Çalışma zamanında nesne üretir mi?HayırEvet
Kullanım biçimi"paid" gibi doğrudan değerler gibi üyeler
JavaScript tarafından okunabilir mi?HayırEvet
Derlenmiş çıktıya ek kod etkisiYokturEnum türüne göre olabilir
Dış API veya JSON ile uyumString değerlerle doğrudan ve açıktırÜyelerin gerçek değerleri ayrıca belirlenmelidir
Basit sabit değer kümeleri için uygunlukGenellikle daha uygundurÇalışma zamanı ihtiyacı varsa uygundur
Tablodaki ayrımın önemli noktası şudur: Union type bir tip açıklaması, enum ise hem tip hem de çalışma zamanı değeridir. Bu nedenle birini diğerinin yalnızca farklı yazılmış biçimi gibi değerlendirmemek gerekir.

Union type ne zaman tercih edilmeli?​


Değerler yalnızca tip güvenliği için gerekiyorsa​


Bir fonksiyonun veya nesnenin kabul edebileceği seçenekleri sınırlamak istiyorsanız union type çoğu durumda yeterlidir. Örneğin bir bileşenin görünüm türünü sınırlamak için çalışma zamanında ayrıca bir sabit nesneye ihtiyaç yoksa şu tanım sade ve doğrudandır:

Kod:
type ButtonVariant = "primary" | "secondary" | "danger";

type ButtonProps = {
  variant: ButtonVariant;
  label: string;
};

const button: ButtonProps = {
  variant: "primary",
  label: "Kaydet"
};

variant alanına "outline" gibi tanımlanmamış bir değer verirseniz derleyici hata bildirir. Buradaki amaç seçenekleri çalışma zamanında listelemek değil, geliştiricinin yanlış değer yazmasını önlemektir. Bu nedenle union type uygun seçimdir.

JSON, URL veya veritabanı değerleriyle çalışıyorsanız​


Dış sistemlerden gelen değerler çoğunlukla "pending", "paid" veya "cancelled" gibi string değerlerdir. String union, bu değerleri dönüştürmeden tip tanımına bağlar:

Kod:
type Role = "admin" | "editor" | "viewer";

type User = {
  role: Role;
};

function canEdit(user: User): boolean {
  return user.role === "admin" || user.role === "editor";
}

Bu yaklaşım JSON ile gönderilen değerlerin açıkça görünmesini sağlar. Ancak TypeScript tipi, dışarıdan gelen verinin gerçekten geçerli olduğunu çalışma zamanında kanıtlamaz. Bir API "unknown" veya hatalı bir değer gönderirse union type bunu kendiliğinden doğrulamaz. Bu durumda ayrıca çalışma zamanı doğrulaması gerekir.

Örneğin veri dışarıdan geliyorsa yalnızca şu tür tanımına güvenmek yeterli değildir:

Kod:
type Role = "admin" | "editor" | "viewer";

const role = response.role as Role;

as Role ifadesi veriyi doğrulamaz; yalnızca derleyiciye bu değeri o türde kabul etmesini söyler. Gerçek doğrulama için izin verilen değerleri çalışma zamanında kontrol eden bir fonksiyon veya doğrulama kütüphanesi kullanmalısınız.

Küçük ve nadiren değişen bir seçenek kümeniz varsa​


Birkaç sabit seçenek doğrudan kod içinde karşılaştırılıyor ve seçenekleri döndürmek, etiketlemek veya başka özelliklerle eşleştirmek gerekmiyorsa union type daha az ek yapı oluşturur. Tip tanımı ile kullanım yeri arasındaki ilişki de açıktır:

Kod:
type LogLevel = "debug" | "info" | "warn" | "error";

function writeLog(level: LogLevel, message: string) {
  console.log(`[${level}] ${message}`);
}

Bu örnekte LogLevel için ayrıca JavaScript nesnesi üretmenin belirgin bir faydası yoktur. Enum eklemek, ihtiyacı karşılamadan yeni bir çalışma zamanı yapısı ve adlandırma katmanı getirebilir.

Enum ne zaman daha uygun olabilir?​


Değerleri çalışma zamanında dolaşmanız gerekiyorsa​


Kullanıcıya seçenek listesi göstermek, bütün değerler üzerinde döngü kurmak veya değerleri başka bilgilerle eşleştirmek istiyorsanız yalnız union type yeterli olmaz. Çünkü union type çalışma zamanında mevcut değildir.

Bu durumda açık bir sabit nesne çoğu projede enum'a alternatif olarak da kullanılabilir:

Kod:
const OrderStatus = {
  Pending: "pending",
  Paid: "paid",
  Shipped: "shipped",
  Cancelled: "cancelled"
} as const;

type OrderStatus = typeof OrderStatus[keyof typeof OrderStatus];

const options = Object.entries(OrderStatus);

Burada OrderStatus hem çalışma zamanında kullanılabilen bir nesnedir hem de OrderStatus türü bu nesnenin değerlerinden türetilir. Böylece tek tek aynı string değerleri iki farklı yerde yazma ihtiyacı azalır.

Aynı ihtiyaç enum ile de karşılanabilir:

Kod:
enum OrderStatus {
  Pending = "pending",
  Paid = "paid",
  Shipped = "shipped",
  Cancelled = "cancelled"
}

const options = Object.values(OrderStatus);

Seçim burada proje kurallarına ve ekip tercihine bağlıdır. Sabit nesne, JavaScript nesnesi olduğunu daha açık gösterir ve JSON değerleriyle çalışırken doğrudan string değerleri korur. Enum ise üyeleri tek bir ad altında toplamak isteyen ekipler için daha kısa ve tanıdık olabilir.

Değer ve ad ayrımını özellikle korumak istiyorsanız​


Enum üyeleri, geliştiricinin kullandığı ad ile gerçek değeri ayırabilir:

Kod:
enum PaymentMethod {
  CreditCard = "credit_card",
  BankTransfer = "bank_transfer"
}

Kod içinde PaymentMethod.CreditCard kullanılırken API'ye "credit_card" gönderilebilir. Bu ayrım özellikle dış sistemin kullandığı değerlerin geliştirici açısından daha okunabilir isimlerden farklı olduğu durumlarda yararlıdır.

Bununla birlikte JSON gönderirken enum üyesini değil, serileştirme sonucunda gerçekten hangi değerin gönderildiğini kontrol etmelisiniz. Enum adı CreditCard ile dış sistemin beklediği credit_card aynı şey değildir. Bu nedenle API sözleşmesindeki değerleri sabit ve açık biçimde tanımlamak gerekir.

String enum, sayısal enum ve sabit nesne arasındaki seçim​


Enum kullanacaksanız çoğu uygulama kodunda string enum daha öngörülebilirdir:

Kod:
enum AccessLevel {
  Read = "read",
  Write = "write",
  Admin = "admin"
}

Sayısal enum'larda değerler açıkça verilmezse otomatik numaralandırma devreye girebilir. Bu değerler bir API'ye, dosyaya veya veritabanına yazılacaksa otomatik numaralara güvenmek risklidir; enum üyelerinin sırası değiştiğinde dışarıdaki anlam bozulabilir. Dış sistemle veri alışverişinde sabit string değerler kullanmak bu riski azaltır.

Ayrıca union type ile enum arasında karar veremediğinizde şu pratik sırayı izleyebilirsiniz:
  1. Değerler yalnızca derleme sırasında kontrol edilecekse union type tanımlayın.
  2. Değerleri çalışma zamanında listelemeniz veya bir nesne olarak kullanmanız gerekiyorsa sabit nesne ya da enum seçin.
  3. Değerler JSON, URL veya API ile dışarı çıkıyorsa gerçek string değerleri açıkça belirleyin.
  4. Dışarıdan gelen veriyi yalnızca TypeScript türüyle doğrulanmış saymayın; çalışma zamanı kontrolü ekleyin.
  5. Ekipte mevcut bir kod standardı varsa yeni tanımları aynı yaklaşımla sürdürün; aynı kavram için bir yerde enum, başka yerde union type kullanarak gereksiz dönüşüm oluşturmayın.

Sık yapılan hatalar ve doğru sonraki adım​


Union type kullandığınız hâlde değerleri çalışma zamanında almak istiyorsanız şu tür bir kod çalışmaz:

Kod:
type Status = "pending" | "paid" | "shipped";

// Object.values(Status); // Hata: Status yalnızca bir türdür

Bunun anlamı, union type'ın eksik veya bozuk olduğu değil, çalışma zamanında bir değere dönüşmediğidir. Değerleri listelemeniz gerekiyorsa sabit bir dizi veya nesne tanımlayın ve türü bundan türetin:

Kod:
const statuses = ["pending", "paid", "shipped"] as const;
type Status = typeof statuses[number];

function isStatus(value: string): value is Status {
  return (statuses as readonly string[]).includes(value);
}

Bu örnekte statuses çalışma zamanında vardır, Status ise bu listenin elemanlarından türetilir. isStatus fonksiyonu string türündeki bir değerin izin verilen değerlerden biri olup olmadığını kontrol eder. Fonksiyonun true döndürmesi, o belirli değerin tanımlanan kümede bulunduğunu gösterir; dış verinin başka iş kurallarına da uygun olduğunu kanıtlamaz.

Tersine, enum kullandığınız hâlde API'nin string beklediği durumda enum üyesinin gerçek değerini kontrol edin. API "paid" beklerken sayısal enum üyesi veya yanlış bir ad gönderilirse TypeScript derlemesi başarılı olsa bile istek uygulama düzeyinde reddedilebilir. Böyle bir durumda tür tanımını API sözleşmesindeki gerçek değerlerle eşleştirip serileştirilen isteği inceleyin.

Kısa karar kuralı​


Union type seçin: Değer kümesi küçükse, amaç yalnızca tip güvenliğiyse, çalışma zamanında değerleri dolaşmayacaksanız ve string değerleri doğrudan kullanmak istiyorsanız.

Enum veya sabit nesne seçin: Değerleri çalışma zamanında listelemeniz, tek bir ad altında kullanmanız, etiketler veya başka özelliklerle eşleştirmeniz gerekiyorsa.

Dış API ile çalışan modern TypeScript kodunda sabit string dizisi ya da as const nesnesi, hem çalışma zamanı değerlerini hem de bu değerlerden türetilen tipi birlikte yönetmek için güçlü bir orta yol sunar. Son karar, enum kullanma alışkanlığından çok çalışma zamanında gerçekten bir değere veya değer listesine ihtiyaç olup olmadığına göre verilmelidir.

Sık sorulan sorular​

Union type değerlerini çalışma zamanında nasıl kontrol ederim?​

Union type tek başına çalışma zamanında kontrol edilemez. İzin verilen değerleri bir dizi veya nesnede ayrıca tutup includes, Object.values ya da özel bir type guard ile doğrulamanız gerekir.

Enum kullanmak her zaman daha güvenli midir?​

Hayır. Enum, derleme sırasında belirli değerleri sınırlayabilir; ancak dışarıdan gelen JSON verisinin gerçekten enum üyelerinden biri olduğunu kendiliğinden doğrulamaz. Dış veriler için ayrıca çalışma zamanı doğrulaması gerekir.

API değerleri için enum mu, union type mı kullanılmalı?​

API yalnızca sabit string değerler kullanıyorsa union type veya bu değerlerden türetilen as const yapı genellikle anlaşılırdır. Değerleri çalışma zamanında da listelemeniz gerekiyorsa sabit nesne veya enum tercih edebilirsiniz; her iki durumda da dış sistemin beklediği gerçek değerleri açıkça tanımlayın.

Aynı projede enum ve union type birlikte kullanılabilir mi?​

Evet, ancak aynı kavram için iki ayrı kaynak oluşturmamaya dikkat edin. Bir yerde enum, başka yerde aynı değerleri içeren bağımsız union type tanımlamak zamanla uyumsuzluk doğurabilir. Ortak değerleri tek bir sabit nesne, dizi veya enum üzerinden türetmek daha güvenlidir.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Foruma git ?

Bu konuyu görüntüleyen kullanıcılar

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic