typeof TypeScript'te iki anlama gelir. Bir ifadede JavaScript operatörüdür: çalışır, "string" veya "number" gibi bir string döndürür ve siz o string'i karşılaştırdığınızda TypeScript değişkeni daraltır. Bir tip konumunda ise bir tip sorgusudur: typeof config, config değişkeninin statik tipini verir.
Son satır farkı gösteriyor: bir console.log içindeki typeof custom çalışma zamanı operatörüdür ve object yazdırır; type Options = sonrasındaki typeof defaults ise derleme zamanı sorgusudur ve JavaScript'e hiç ulaşmaz.
Bir Bakışta İki Anlam
Çalışma zamanı typeof (JavaScript) | Tip sorgusu typeof (TypeScript) | |
|---|---|---|
| Nerede görünür | Her ifadede: if, return, console.log(...) | Tip konumlarında: : sonrası, type X = ... içinde, <...> içinde |
| Örnek | typeof x === "string" | let y: typeof x; |
| Ne zaman değerlendirilir | Kod çalıştığında | Derleyici tarafından, sonra silinir |
| Sonuç | Sekiz string'den biri | Bir tip |
| Ne için kullanılır | Bir değeri kontrol edip tipini daraltmak | Bir değerden tip türetmek |
TypeScript onları konuma göre ayırt eder, bu yüzden aynı anahtar kelime hiçbir zaman aynı anda ikisini birden ifade etmez.
Çalışma Zamanında typeof Sonuçları
Çalışma zamanı operatörü sekiz string'den birini döndürür. Yaygın değerlerin ne verdiğini görmek için bunu çalıştırın:
| Değer | typeof sonucu | Not |
|---|---|---|
"hi", template string'ler | "string" | |
42, 3.14, NaN, Infinity | "number" | NaN bir sayıdır; Number.isNaN ile kontrol edin |
10n | "bigint" | |
true, false | "boolean" | |
undefined | "undefined" | |
Symbol("id") | "symbol" | |
| fonksiyonlar, arrow function'lar, sınıflar | "function" | bir sınıf bir constructor fonksiyondur |
null | "object" | JavaScript'te tarihsel bir hata |
{}, [], new Date(), new Map() | "object" | diziler nesnedir: Array.isArray kullanın |
new String("x"), new Number(1) | "object" | sarmalayıcı nesneler, kaçının |
Düz JavaScript'te hiç bildirilmemiş bir değişken üzerinde typeof hata fırlatmak yerine "undefined" döndürür. TypeScript'te bu kod derlenmez: Cannot find name 'notDeclared'. (TS2304).
typeof ile Daraltmak
Bir if, bir switch, bir ternary içinde ya da && sonrasındaki bir typeof karşılaştırması, değişkeni her dalda daraltır. Primitive'lerden oluşan bir union'ı ele almanın standart yolu ve unknown üzerinde başvurulacak ilk kontroldür.
typeof x !== "string" diğer yöne, yani string dışındaki her şeye daraltır. Ayrıca derleyici olası sekiz string'i bildiği için karşılaştırmadaki bir yazım hatası, sessizce hep false olan bir kontrol yerine bir derleme hatasıdır:
Derleyici index.ts(3,7): error TS2367: This comparison appears to be unintentional because the types '"bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"' and '"strnig"' have no overlap. yazdırır. Düz JavaScript'te bu yazım hatası her string'i sessizce number yoluna gönderirdi. Yazımı düzeltin, text yazdırır.
typeof null Tuzağı
typeof null sonucu "object" olduğu için TypeScript typeof x === "object" ifadesini object değil, object | null tipine daraltır. Bir null kontrolü ekleyin, yoksa bir özellik okumak hatadır (TS18047 'x' is possibly 'null'.).
typeof dizileri, tarihleri, map'leri ve düz nesneleri birbirinden ayıramaz: hepsi "object" olur. Diziler için Array.isArray(x), sınıf örnekleri için x instanceof Date kullanın. Interface'ler silindiği için ne typeof ne de başka bir şey bir değerin bir interface ile eşleşip eşleşmediğini çalışma zamanında kontrol edebilir; bunun için özellikleri kontrol eden bir type guard fonksiyonu yazın.
Tip Konumlarında typeof
Bir tipte typeof someVariable, TypeScript'in o değişken için çıkardığı (ya da sizin bildirdiğiniz) tipi kopyalar. Zaten var olan bir değer için tipi elle yazmaktan kurtarır ve ikisini senkron tutar.
const theme = {
primary: "#3178c6",
spacing: 8,
dark: false,
};
type Theme = typeof theme;
// { primary: string; spacing: number; dark: boolean }
function withSpacing(t: Theme, factor: number): Theme {
return { ...t, spacing: t.spacing * factor };
}
console.log(withSpacing(theme, 2)); // { primary: '#3178c6', spacing: 16, dark: false }
let userName = "Ada";
const fixed = "Ada";
type A = typeof userName; // string
type B = typeof fixed; // "Ada" (a const keeps its literal type)
Sonuç, değişkenin nasıl bildirildiğine bağlıdır: bir let ya da bir nesne özelliği genişletilir (string, number), bir const primitive ise literal tipini korur. Bir nesneye veya diziye as const ekleyin, typeof en alt seviyeye kadar readonly literal tipler verir. typeof özellik erişimini de kabul eder, typeof theme.spacing sonucu number olur; ama keyfi ifadeleri kabul etmez: type T = typeof getTheme(); bir sözdizimi hatasıdır (';' expected., TS1005). Bir çağrının döndürdüğü tip için ReturnType<typeof getTheme> kullanın.
keyof typeof: Bir Nesnenin Anahtarları Tip Olarak
keyof typeof obj en yaygın birleşimdir. typeof nesneyi bir tipe çevirir, keyof anahtarlarını alır ve nesne değiştikçe doğru kalan, özellik adlarından oluşan bir union elde edersiniz.
Aynı numara sabit bir dizi üzerinde değerlerinin bir union'ını verir: const roles = ["admin", "editor"] as const ile (typeof roles)[number] tipi "admin" | "editor" olur. as const olmadan yalnızca string olurdu. keyof tek başına keyof sayfasında anlatılıyor.
ReturnType<typeof fn> ve Sınıflarda typeof
ReturnType ve Parameters gibi utility tipler bir fonksiyon tipi alır. Bir fonksiyon adı bir değerdir, bu yüzden onu önce typeof üzerinden geçirin:
ReturnType<createUser> yazmak 'createUser' refers to a value, but is being used as a type here. Did you mean 'typeof createUser'? (TS2749) ile başarısız olur; derleyici tam olarak bunu istiyor.
Sınıflar, bir adın hem değer hem tip olduğu tek durumdur. Tip olarak User sınıfın bir örneği anlamına gelir; typeof User ise statik üyeleri dahil sınıfın kendisi, yani constructor anlamına gelir:
class Point {
static origin = new Point(0, 0);
constructor(public x: number, public y: number) {}
}
const p: Point = new Point(1, 2); // an instance
const Ctor: typeof Point = Point; // the class (constructor + statics)
const q = new Ctor(3, 4); // q: Point
type Instance = InstanceType<typeof Point>; // Point
typeof, instanceof ve Type Guard
| Kontrol | Neyle çalışır | Örnek |
|---|---|---|
typeof | primitive'ler, fonksiyonlar, "bir nesne mi" | typeof x === "number" |
Array.isArray | diziler | Array.isArray(x) |
instanceof | sınıf örnekleri (Date, Error, kendi sınıflarınız) | x instanceof Date |
in | özelliğe göre nesne union'ları | "email" in x |
| Type guard fonksiyonu | interface'ler, type alias'lar, geri kalan her şey | x is User ile isUser(x) |
İşe uyan en dar aracı seçin. Sınıf örnekleri için instanceof sayfasına bakın; bir interface ile tanımlanmış biçimler için kullanılabilen tek çalışma zamanı kontrolü bir type guard fonksiyonudur.
Sıkça Sorulan Sorular
TypeScript'te typeof ne yapar?
Göründüğü yere göre iki farklı şey. Bir ifadede typeof x JavaScript operatörüdür: çalışır ve "string" veya "object" gibi bir string döndürür; o string'i karşılaştırdığınızda TypeScript x değerini daraltır. Bir tip notasyonunda ise typeof x bir tip sorgusudur: derleyici tarafından değerlendirilir, x değişkeninin statik tipini verir ve üretilen JavaScript'ten kaybolur.
TypeScript'te keyof typeof nedir?
keyof typeof obj, bir nesnenin özellik adlarının string literal tiplerinden oluşan union'ını verir. typeof obj nesne değerini onun tipine çevirir, keyof da o tipin anahtarlarını alır. const colors = { red: "#f00", blue: "#00f" } için keyof typeof colors sonucu "red" | "blue" olur.
typeof null neden "object" döndürür?
JavaScript'in ilk sürümünden kalan ve artık web'i bozmadan düzeltilemeyen bir hatadır. TypeScript bunu modeller: typeof x === "object" sonrasında x, object | null tipine daraltılır; bu yüzden özellik okumadan önce x !== null kontrolünü de yapmanız gerekir.
TypeScript'te bir değerin dizi olup olmadığını nasıl kontrol ederim?
Bir dizi tipine daraltan Array.isArray(value) kullanın. typeof bunu yapamaz: typeof [] sonucu, düz nesneler ve null ile aynı şekilde "object" olur.
TypeScript'te typeof ile instanceof arasındaki fark nedir?
typeof bir değerin primitive kategorisini kontrol eder ("string", "number", "function", "object"...). instanceof ise bir nesnenin Date ya da kendi class User sınıfınız gibi belirli bir sınıf veya constructor tarafından oluşturulup oluşturulmadığını kontrol eder. Primitive'ler için typeof, sınıf örnekleri için instanceof kullanın; hiçbiri çalışma zamanında var olmayan bir interface'i veya type alias'ı kontrol edemez.