Meydan okuma 3: Branded + phantom
- TypeScript kursu
- İleri seviye
- Ders 56/57
- 6 dk
Branded ve phantom türlerini birleştiren bir görev çözersin.
Branded + phantom türler
Branded türler, ilkel bir değere benzersiz bir sembol imzası ekleyerek aynı temel türe sahip ama karıştırılmaması gereken nominel türler yaratır. Phantom türler ise yalnızca derleme zamanında var olan ve çalışma zamanında kullanılmayan bir tür parametresiyle durumu kodlar.
declare const __brand: unique symbol;
type Brand<T, B> = T & { readonly [__brand]: B };
type UserId = Brand<string, "UserId">;
type OrderId = Brand<string, "OrderId">;
// UserId ve OrderId artık birbirine atanamazİkisini birleştirerek çalışma zamanında güvenli, derleme zamanında durum belirli API'ler kurabilirsin.
Uygulama Brand türü tanımla
__brand adında unique symbol tanımla ve Brand<T, B> = T & { readonly [__brand]: B } türünü yaz. UserId = Brand<string, "UserId"> ve Email = Brand<string, "Email"> alias'larını oluştur, her birinden bir değer yap ve uid'i yazdır.
Başlangıç kodu
// Brand<T, B> tanımla
// UserId = Brand<string, "UserId">
// Email = Brand<string, "Email">
// her ikisinden bir değer oluştur, UserId değerini yazdırÖrnek çözüm
declare const __brand: unique symbol;
type Brand<T, B> = T & { readonly [__brand]: B };
type UserId = Brand<string, "UserId">;
type Email = Brand<string, "Email">;
const uid: UserId = "u123" as UserId;
const em: Email = "a@b.com" as Email;
console.log(uid);Beklenen çıktı
u123
Uygulama Phantom durumlu kutu
Box<S> türünü yaz: S "Open" | "Sealed" ile kısıtlı phantom parametre, Brand<{ value: number }, `Box_${S}`> olsun. open(b: Box<"Sealed">): Box<"Open"> fonksiyonu b.value'yu yeni bir kutu olarak döndürsün. Mühürlü bir kutu oluştur, open çağır ve value'yu yazdır.
Başlangıç kodu
// Brand ve phantom birleştir
// Box<S>: S = "Open" | "Sealed" phantom durumu
// open: mühürlü kutuyu açılır kutuya çevirir
// bir mühürlü kutu oluştur, open çağır, value'yu yazdırÖrnek çözüm
declare const __brand: unique symbol;
type Brand<T, B> = T & { readonly [__brand]: B };
type Box<S extends "Open" | "Sealed"> = Brand<{ value: number }, `Box_${S}`>;
function open(b: Box<"Sealed">): Box<"Open"> {
return { value: b.value } as Box<"Open">;
}
const sealed: Box<"Sealed"> = { value: 7 } as Box<"Sealed">;
const opened = open(sealed);
console.log(opened.value);Beklenen çıktı
7
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Aşağıdaki tanımlardan sonra hangi satır derlenir?
declare const __brand: unique symbol;
type Brand<T, B> = T & { readonly [__brand]: B };
type UserId = Brand<string, "UserId">;
type OrderId = Brand<string, "OrderId">;- let u: UserId = "x" as UserId; Doğru cevap
- let u: UserId = 5 as UserId;
- let u: UserId = "x" as OrderId;
- let o: OrderId = "x" as UserId;
Açıklama: Branded türler nominel gibi davranır; yalnızca aynı markaya ve aynı temel türe sahip değerler birbirine atanabilir. Farklı marka veya yanlış temel tür derleme hatası verir.
2 Brand sembolü
declare const __brand: ____;
type Brand<T, B> = T & { readonly [__brand]: B };
declare const __brand: unique symbol;
type Brand<T, B> = T & { readonly [__brand]: B };
Açıklama: Brand'in gerçekten benzersiz olması için `unique symbol` gerekir; sıradan `symbol` computed key olarak tür konumunda kullanılamaz.
3 Branded ve phantom parçaları
| Kavram | Anlamı |
|---|---|
Branded type |
nominel davranış için sembol imzası |
Phantom type |
çalışma zamanında kullanılmayan tür parametresi |
unique symbol |
benzersiz anahtar garanti eder |
as UserId |
değeri markalı türe yükseltir |