Literal tip, tam olarak tek bir değeri olan bir tiptir: "up" tek üyesi "up" string'i olan bir tiptir, 404 ise tek üyesi 404 sayısı olan bir tiptir. Tek başlarına pek kullanışlı değildirler. Bir union'da birleştirildiklerinde, sabit bir değer kümesini kabul eden ve başka hiçbir şeyi kabul etmeyen bir değişken elde edersiniz.
@ts-expect-error yorumu olmadan son çağrı bir derleme zamanı hatasıdır (TS2345). Yorumla birlikte program derlenir ve çağrı yine çalışıp moving north by 1 yazdırır: literal tipler yalnızca derleyici için vardır, çalışma zamanında değer sıradan bir string'dir.
String, Number ve Boolean Literal'leri
Her string, number, bigint veya boolean değeri bir tip olarak yazılabilir. Derleyici bu durumda yalnızca o tam değeri kabul eder.
let method: "GET" = "GET";
let code: 404 = 404;
let ok: true = true;
let big: 10n = 10n;
type Port = 80 | 443 | 8080;
const port: Port = 443;
boolean tipinin kendisi yalnızca true | false union'ıdır; bir boolean değerini if (flag) ile daralttığınızda else dalında false kalmasının nedeni budur.
| Literal tip | İzin verdiği | Daha geniş tip |
|---|---|---|
"GET" | yalnızca "GET" string'i | string |
404 | yalnızca 404 sayısı | number |
10n | yalnızca bigint 10 | bigint |
true | yalnızca true | boolean |
Literal Union'ları
Yaygın kullanım, izin verilen her değeri listeleyen bir union'dır. Fonksiyonun içinde derleyici siz kontrol ettikçe union'ı daraltır, böylece her dal elindeki değerin tam olarak ne olduğunu bilir.
String literal union'ı, TypeScript'te enum'a karşı alışılmış alternatiftir. Çalışma zamanında hiçbir maliyeti yoktur, değerler loglayabileceğiniz ve JSON ile gönderebileceğiniz düz string'lerdir ve bir yazım hatası derleme hatası olur. Artıları ve eksileri enum'lar sayfasında.
Genişleme: let ile const
TypeScript bir literal'den tip çıkarırken değerin değişip değişemeyeceğine bakar. Bir const değişkeni asla yeniden atanamaz, bu yüzden literal tipini korur. Bir let değişkeni atanabilir, bu yüzden tipi genel tipe genişletilir.
Çıkarılan tipi görmek için editörde her adın üzerine gelin. Yalnızca belirli değerleri tutan bir let istiyorsanız ona notasyon yazın: let mode: "light" | "dark" = "light".
Nesne Özellikleri Neden Genişler
Bir nesne literal'inin özellikleri değiştirilebilir, bu yüzden nesne bir const içinde saklansa bile onlar da genişler. Literal tiplerle kazara karşılaşmanın en yaygın yolu budur:
Derleyici şunu bildirir:
index.ts(7,15): error TS2345: Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.
req, { url: string; method: string } olarak çıkarılır, çünkü daha sonraki bir kod req.method = "DELETE" çalıştırabilir. Üç çözüm var:
Dördüncü seçenek satisfies kullanmaktır; nesneyi bir tipe karşı kontrol ederken literal özellik tiplerini korur.
as const
as const bir const assertion'dır. Bir ifadenin sonuna koyun, derleyici çıkarabileceği en dar tipi çıkarır:
- string, number ve boolean değerleri literal tiplerini korur
- nesne özellikleri
readonlyolur - dizi literal'leri sabit uzunluklu
readonlytuple'lara dönüşür
Assertion yalnızca derleme zamanında geçerlidir. Üretilen JavaScript, as const kaldırılmış aynı nesne literal'idir; bu yüzden başka bir kodun onu çalışma zamanında değiştirmesini hiçbir şey engellemez. Çalışma zamanı garantisine ihtiyacınız varsa Object.freeze de çağırın.
as const Bir Diziden Union Tip
Sık görülen bir kalıp, izin verilen değerleri çalışma zamanında üzerinde dolaşabileceğiniz tek bir dizide tutmak ve union tipini ondan türetmektir. (typeof arr)[number], "arr dizisinin herhangi bir elemanının tipi" anlamına gelir.
as const olmadan ROLES bir string[] olurdu ve Role düz string olurdu. isRole içindeki readonly string[] dönüşümü gereklidir, çünkü literal'lerden oluşan bir tuple üzerindeki includes yalnızca o literal'leri kabul eder ve fonksiyonun amacı onlardan biri olmayabilecek bir string'i test etmektir. Aynı kalıp anahtar/değer eşlemeleri için nesnelerle de çalışır: const Status = { Active: "active", Banned: "banned" } as const, ardından type Status = (typeof Status)[keyof typeof Status].
const Tip Parametreleri
Generic bir fonksiyon normalde ona verdiğiniz literal'leri genişletir. TypeScript 5.0'dan beri bir tip parametresini const olarak işaretleyebilirsiniz; bu, derleyicinin argümanı çağırana yazdırmadan, üzerinde as const varmış gibi çıkarmasını sağlar.
Bu çoğunlukla kütüphane yazarları için bir araçtır: route tanımları, builder'lar ve şema yardımcıları onu kullanır, böylece çağıranlar düz literal'lerden kesin tipler elde eder.
const'un Anlamları
const anahtar kelimesi TypeScript kodunda dört farklı yerde karşınıza çıkar:
| Sözdizimi | Türü | Ne yapar |
|---|---|---|
const x = 1 | JavaScript bildirimi | bağlama yeniden atanamaz; literal bir değer literal tipini korur |
expr as const | TypeScript assertion'ı | en dar tip: literal'ler, readonly özellikler, readonly tuple'lar |
function f<const T>() | TypeScript tip parametresi | argümanları üzerlerinde as const varmış gibi çıkarır |
const enum E {} | TypeScript enum'ı | üyeleri derleme zamanında yerine yazılan bir enum |
Hiçbiri bir nesneyi çalışma zamanında dondurmaz. const obj = { a: 1 } yine de obj.a = 2 yapılmasına izin verir; yalnızca obj değişkeninin kendisini yeniden atamak hatadır.
Sıkça Sorulan Sorular
TypeScript'te literal tip nedir?
Tam olarak tek bir değere izin veren bir tiptir. "GET", tek değeri "GET" string'i olan bir tiptir; 404, tek değeri 404 sayısı olan bir tiptir; true da tek değeri true olan bir tiptir. En çok type Method = "GET" | "POST" gibi union'larda birleştirildiklerinde işe yararlar.
TypeScript'te as const ne yapar?
as const bir const assertion'dır. Derleyiciye bir ifade için en dar tipi çıkarmasını söyler: string ve number değerleri literal tiplerini korur, nesne özellikleri readonly olur ve dizi literal'leri readonly tuple'lara dönüşür. Yalnızca tipi değiştirir; çalışma zamanındaki değer aynı düz nesne veya dizidir ve dondurulmaz.
TypeScript neden benim literal'im yerine string çıkarıyor?
Çünkü değer değiştirilebilir. let x = "a" ve { method: "GET" } içindeki özellik daha sonra yeniden atanabilir, bu yüzden TypeScript onları string tipine genişletir. Bir const değişkeni ise "a" literal tipini korur. Bir nesnenin içindeki literal'leri korumak için ona literal tiple notasyon yazın, as const ya da satisfies kullanın.
const ile as const arasındaki fark nedir?
const bir JavaScript bildirimidir: değişken yeniden atanamaz ama işaret ettiği nesne yine değiştirilebilir. as const bir TypeScript tip assertion'ıdır: değerin her özelliğini tip sisteminde readonly ve literal yapar. Hiçbiri nesneyi çalışma zamanında dondurmaz; bunun için Object.freeze kullanın.
Bir string dizisinden nasıl union tip elde ederim?
Diziyi as const ile tanımlayın, sonra tipini number ile indeksleyin: const roles = ["admin", "user"] as const; type Role = (typeof roles)[number]; ifadesi "admin" | "user" verir. as const olmadan dizi string[] olur ve sonuç yalnızca string olur.