TypeScript
Meydan okuma 3: Branded + phantom
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.
Örnek çözümü göster
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);
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.
Örnek çözümü göster
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);
Kendini test et
-
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;
- let u: UserId = 5 as UserId;
- let u: UserId = "x" as OrderId;
- let o: OrderId = "x" as UserId;
Cevabı göster
let u: UserId = "x" as UserId; — 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.
-
Brand sembolü
declare const __brand: ____;
type Brand<T, B> = T & { readonly [__brand]: B };
Cevabı göster
declare const __brand: unique symbol;
type Brand<T, B> = T & { readonly [__brand]: B };
-
Branded ve phantom parçaları
- 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
Sıradaki ders: Meydan okuma 4: Mini derleyici