Menu

TypeScript instanceof: Sınıfları ve Hataları Daraltmak

instanceof, bir nesnenin bir sınıf tarafından oluşturulup oluşturulmadığını çalışma zamanında kontrol eder ve TypeScript değişkeni o sınıfa daraltır. Kendi sınıflarınız ve Error alt sınıflarıyla nasıl çalıştığı, neden interface'leri veya type alias'ları kontrol edemediği ve nerede şaşırtıcı cevaplar verdiği.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

value instanceof SomeClass, çalışma zamanında çalışan bir JavaScript kontrolüdür: SomeClass.prototype nesnenin prototip zincirindeyse, yani nesne new SomeClass (veya bir alt sınıf) ile oluşturulduysa true olur. TypeScript kontrolün içinde value değerini SomeClass tipine daraltır.

Sınıflardan oluşturulmuş nesneler için instanceof, primitive'ler için typeof kullanın. Burada ikisi de gerekli: instanceof Date değerini ayırır, sonra typeof kalanı böler.

Kendi Sınıflarınızı Daraltmak

instanceof, true dalında sınıfa daraltır ve false dalında onu çıkarır; böylece sınıflardan oluşan bir union üye üye ele alınabilir.

Bir alt sınıf örneği ebeveyni için de kontrolü geçer: Square extends Rect ise new Square(2) instanceof Rect sonucu true olur. Dallar farklıysa önce en özel sınıfı test edin.

catch İçinde Error Alt Sınıfları

instanceof en çok catch içinde kullanılır. strict altında yakalanan değer unknown olur (her şey fırlatılabilir) ve tipli bir hataya geri dönmenin yolu instanceof kullanmaktır.

Çıktı:

404: /missing.txt
TypeError: path must be absolute

class X extends Error, TypeScript 7'nin desteklediği her target'ta (ES2015 ve sonrası) instanceof ile çalışır. Constructor içinde Object.setPrototypeOf(this, X.prototype) çağırma yönündeki eski tavsiye, TypeScript 7'nin kaldırdığı bir target olan ES5'e derlenen kod içindi.

instanceof Interface'ler veya Tiplerle Çalışmaz

Interface'ler ve type alias'lar yalnızca derleyici için vardır. Derlemeden sonra karşılaştırılacak bir User değeri yoktur, bu yüzden TypeScript kontrolü reddeder:

Derleyici index.ts(8,24): error TS2693: 'User' only refers to a type, but is being used as a value here. bildirir. İki çözüm vardır. Biçimi bir type guard ile, yani value is User döndüren bir fonksiyonla kendiniz kontrol edin:

Ya da bu nesneleri sizin kodunuz oluşturuyorsa User tipini bir sınıf yapın ve onları new ile oluşturun; o zaman instanceof çalışır. Predicate'leri ve assertion fonksiyonlarını type guard'lar sayfası ayrıntılı anlatıyor.

Doğru Tip, Doğru Örnek Değildir

TypeScript tipleri yapıya göre karşılaştırır: bir sınıfla aynı üyelere sahip bir nesne literal'i sınıf tipine atanabilir. instanceof yapıya bakmaz. Prototip zincirinde dolaşır ve hiç new ile oluşturulmamış bir nesne, derleyici onu o tip olarak kabul etse bile kontrolden geçemez.

Son satır önemlidir. structuredClone, JSON.parse(JSON.stringify(...)) ve worker'lar arasındaki mesajlar, statik tipleri hâlâ Point diyebilse de sınıf prototipi olmayan düz nesneler döndürür. Sınıf örnekleri böyle bir sınırı geçtiğinde, instanceof veya metotlara güvenmeden önce onları yeniden oluşturun (new Point(copy.x, copy.y)).

instanceof ve Primitive'ler

Primitive'ler (string, number, boolean...) nesne değildir ve prototip zincirleri yoktur, bu yüzden "hi" instanceof String sonucu false olur. TypeScript bu hatayı yapabildiğinde işaretler: solda string olarak tiplenmiş bir değer varken instanceof TS2358 hatasıdır, The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. Primitive'ler için typeof kullanın.

Değerinstanceof kontrolüSonuç
new Date()instanceof Datetrue
[1, 2]instanceof Arraytrue (ama Array.isArray tercih edin)
new TypeError("x")instanceof Errortrue (alt sınıf)
{ x: 1, y: 2 }instanceof Pointfalse (hiç oluşturulmadı)
Object.create(null)instanceof Objectfalse (prototip yok)
"hi"instanceof Stringfalse (primitive)

Farklı Realm'lerden Gelen Değerler

instanceof belirli tek bir constructor nesnesiyle karşılaştırır. Başka bir realm'de (bir iframe veya bir Node vm bağlamı) çalışan kodun kendi Array, Error ve Date nesneleri vardır, bu yüzden orada oluşturulan bir dizi burada instanceof Array kontrolünden geçemez. Aynı npm paketinin iki kopyası node_modules içine düştüğünde de aynısı olur: her kopyanın kendi sınıfı vardır ve birinden gelen bir örnek diğerine karşı instanceof kontrolünden geçemez. Diziler için Array.isArray realm'ler arasında çalışır. Kendi tipleriniz için bir özelliği kontrol etmek (bir type guard ya da bir kind alanı) sorunu tamamen ortadan kaldırır.

Sıkça Sorulan Sorular

TypeScript'te bir nesnenin bir sınıfın örneği olup olmadığını nasıl kontrol ederim?

value instanceof ClassName kullanın. Bir çalışma zamanı kontrolüdür (düz JavaScript) ve TypeScript if içinde value değerini ClassName tipine daraltır. Kendi sınıflarınızın yanı sıra Date, Map ve Error gibi yerleşik sınıflarla da çalışır.

TypeScript'te instanceof bir interface ile kullanılabilir mi?

Hayır. Interface'ler ve type alias'lar TypeScript JavaScript'e derlenirken silinir, bu yüzden çalışma zamanında karşılaştırılacak bir şey yoktur. Bir User interface'i ile x instanceof User TS2693 hatasıdır, "'User' only refers to a type, but is being used as a value here." Bunun yerine özellikleri bir type guard fonksiyonuyla kontrol edin ya da nesneleri kendiniz oluşturuyorsanız User tipini bir sınıf yapın.

instanceof doğru tipteki bir nesne için neden false döndürüyor?

TypeScript tipleri yapısaldır: bir { x: 1, y: 2 } nesne literal'i aynı üyelere sahipse bir Point sınıf tipine atanabilir. Ama instanceof prototip zincirini kontrol eder ve literal hiçbir zaman new Point ile oluşturulmadığı için sonuç false olur. JSON, structuredClone ya da bir mesaj kanalından geçen ve düz nesne olarak geri dönen sınıf örneklerinde de aynısı olur.

instanceof TypeScript'te özel Error sınıflarıyla çalışır mı?

Evet, her modern target ile. class NotFound extends Error {} sonrasında err instanceof NotFound sonucu true olur. false döndürdüğü eski sorun yalnızca ES5'e derlenen çıktıyı etkiliyordu ve TypeScript 7 artık ES5 target'ını desteklemiyor.

"hello" instanceof String neden false?

Bir string literal nesne değil, bir primitive'dir; bu yüzden kontrol edilecek bir prototip zinciri yoktur. instanceof String yalnızca new String() ile oluşturulan sarmalayıcı nesneler için true olur. TypeScript, string olarak tiplenmiş bir değer üzerinde instanceof kullanımını reddeder (TS2358); primitive'ler için typeof value === "string" kullanın.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA