Typcript'te `is` anahtar kelimesi ne işe yarar?


119

Şuna benzeyen bir kodla karşılaştım:

export function foo(arg: string): arg is MyType {
    return ...
}

Ne isdocs ne de google'da arama yapamadım , oldukça yaygın bir kelime ve temelde her sayfada görünüyor.

Anahtar kelime bu bağlamda ne yapar?

Yanıtlar:


133

Daha fazla bilgi için kullanıcı tanımlı tip koruma fonksiyonları referansına bakın .

function isString(test: any): test is string{
    return typeof test === "string";
}

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length); // string function
    }
}
example("hello world");

Tip yüklemi kullanma test is string(yerine sadece kullanmanın yukarıdaki formatta booleandönüş türü için), sonra isString()işlevin döndüreceği, denir true, typescript türünü daralır stringişlevi çağrılmış tarafından korunan herhangi bloğunda. Derleyici düşünürler fooise stringaşağıda korunan bloğunda (ve SADECE korunan aşağıda bloğunda)

{
    console.log("it is a string" + foo);
    console.log(foo.length); // string function
}

Bir tür koşulu yalnızca derleme zamanında kullanılır. Ortaya çıkan .jsdosyanın (çalışma zamanı) TÜR'ü dikkate almadığı için hiçbir farkı olmayacaktır.

Farklılıkları aşağıdaki dört örnekte göstereceğim.

Örnek 1: Yukarıdaki örnek kodda bir derleme hatası veya çalışma zamanı hatası olmayacaktır.

Örnek 2: Aşağıdaki örnek kodda, TypeScript türü daralttığı stringve yönteme toExponentialait olmadığını kontrol ettiği için bir derleme hatası (ayrıca bir çalışma zamanı hatası) olacaktır string.

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
        console.log(foo.toExponential(2));
    }
}

Örnek 3: aşağıdaki örnek kodda bir derleme hatası yoktur, ancak bir çalışma zamanı hatası verecektir çünkü TypeScript, türü YALNIZCA bloke olacak şekilde daraltacaktır, stringancak sonra daraltmayacaktır , bu nedenle foo.toExponentialderleme hatası oluşturmayacaktır (TypeScript bunun bir stringtür olduğunu düşünmez ). Bununla birlikte, çalışma zamanında, yönteme stringsahip değildir toExponential, bu nedenle çalışma zamanı hatası verecektir.

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
    }
    console.log(foo.toExponential(2));
}

Örnek 4: test is string(type yüklemi) kullanmazsak , TypeScript korunan bloktaki türü daraltmaz ve aşağıdaki örnek kodda derleme hatası olmaz, ancak çalışma zamanı hatası verir.

function isString(test: any): boolean{
    return typeof test === "string";
}
function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
        console.log(foo.toExponential(2));
    }
}

Sonuç olarak test is string(tür yüklemi), geliştiricilere kodun bir çalışma zamanı hatası alma şansı olacağını söylemek için derleme zamanında kullanılır. Javascript için, geliştiriciler derleme zamanında hatayı BİLMEYECEKLER. Bu, TypeScript kullanmanın avantajıdır.


14

Bildiğim tek kullanım, örneğinizden biri: arg is MyTypekullanıcı tanımlı bir Tip Korumasında bir "tip koşulu" ( ) belirtmek

Bu referanstaki Kullanıcı Tanımlı Tip Korumalarına bakın

İşte başka bir referans


2
Bunu belgelerde de gördüm, ne kadar tuhaf bir tasarım kararı, bu durum tamamen bir tip döndürülerek ele alınabilir booleandeğil mi?
benjaminz

2
@benjaminz Bu, SO'da kendi sorusunu garanti edebilir, ancak size nasıl farklı olduklarına dair hızlı bir örnek gösterebilirim. isAnahtar kelime aslında kodunda sonra tipi ve kutu yakalamak tip hataları döküm edilir. Daha fazla bilgi için bu örneğe bakın .
styfle

@benjaminz Bir boolean tarafından nasıl işlenebileceğini anlamıyorum. Typecript, bir nesneyi ilettiğiniz işlevin bir tür koruma gibi çalıştığını bilmelidir. Yalnızca type true veya false döndürürse, Typescript bunun gerçekten bir tür koruması olduğunu ve yalnızca nesne doğru ise true döndüren rastgele bir işlev olmadığını nasıl bilebilir. Nesnenin türünü daraltacağını nasıl bilecek? İkincisi, nesnenin türünü hangi türe daraltacağını nasıl bilebilir? Ya parametre üç türden biriyse? Bunun truebelirli bir türe karşılık geldiğini bilmesi gerekir .
pushkin

Tamam belki boole döndürmek işe yaramayabilir, ama neden 'is' operatörünü uygulamıyoruz? function isFish(pet: Fish | Bird): pet is Fish { return (pet as Fish).swim !== undefined; }; if (isFish(pet)){fish.swim()}Yazmak yerine sadece yazabiliriz if (pet is Fish){fish.swim()}.
rkuksin

Öte yandan, tip korumalar OOP açısından kötüdür. Yani, belki de bu şablon, çılgın daktilolar yapmak isteyenler için bir korkuluktur. Bir değişken türünü kontrol etmek istiyorsanız, muhtemelen mimarinizi gözden geçirmelisiniz. Hala
yazım
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.