Daktilo yazısında nedir! (ünlem işareti / patlama) operatörün bir üyeyi silme işlemi sırasında?


454

Bir tslint kuralı için kaynak koduna bakarken, aşağıdaki ifadeyle karşılaştım:

if (node.parent!.kind === ts.SyntaxKind.ObjectLiteralExpression) {
    return;
}

!Sonra operatöre dikkat edin node.parent. İlginç!

Önce dosyayı şu anda yüklü olan TS (1.5.3) sürümüm ile yerel olarak derlemeyi denedim. Ortaya çıkan hata, patlamanın tam yerini gösterdi:

$ tsc --noImplicitAny memberAccessRule.ts 
noPublicModifierRule.ts(57,24): error TS1005: ')' expected.

Sonra, en son TS (2.1.6) sürümüne geçtim. Yani TS 2.x'in özelliği gibi görünüyor. Ancak transpilasyon patlamayı tamamen görmezden geldi ve aşağıdaki JS ile sonuçlandı:

if (node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) {
    return;
}

Google fu'm şimdiye kadar başarısız oldu.

TS'nin ünlem işareti operatörü nedir ve nasıl çalışır?

Yanıtlar:


692

Bu geçersiz olmayan iddianın operatörü. Derleyiciye "bu ifade olamaz nullya da undefinedburada olamaz , bu yüzden nullya da olma olasılığı hakkında şikayet etmeyin " demenin bir yoludur undefined. Bazen tür denetleyicisi bu belirlemeyi kendisi yapamaz.

Bu açıklanmıştır burada :

Yeni bir !düzeltme sonrası ifade işleci, işleneninin null olmadığını ve tür denetleyicisinin bu gerçeği sonuçlandıramadığı bağlamlarda tanımsız olmadığını iddia etmek için kullanılabilir. Özellikle, işlem ile ve hariç tutulan x!tipinde bir değer üretir . Formların iddialarını yazmaya benzer ve , boş olmayan iddia operatör sadece yayılan JavaScript kodunda kaldırılır.xnullundefined<T>xx as T!

Bu açıklamada "iddia" teriminin kullanımını biraz yanıltıcı buluyorum. Geliştiricinin bir testin gerçekleştirileceği anlamında değil , iddia ettiği gibi "iddia" dır. Son satır gerçekten de hiçbir JavaScript kodunun yayılmadığını gösterir.


102
'İddia' belirsizliğine iyi bir çağrı.
Estus Flask

8
İyi açıklama. console.assert()Söz konusu değişken üzerinde bir tane eklemeden önce bunu yapmak için iyi bir uygulama buluyorum !. Add !derleyiciye null denetimi yok saymasını söylediğinden, javascript içindeki noop komutunu derler. Değişkenin boş olmadığından emin değilseniz, açık bir onaylama denetimi yapmanız daha iyi olur.
Jayesh

12
Motive edici bir örnek olarak: dict.has(key) ? dict.get(key) : 'default';TS derleyicisi gibi yeni ES Map türünü kodla kullanmak, getçağrının asla null / undefined döndürmediğini söyleyemez . dict.has(key) ? dict.get(key)! : 'default';türü doğru şekilde daraltır.
kitsu.eb

1
Bu operatör için Elvis operatörünün ikili operatöre nasıl başvurduğu gibi argo var mı?
ebakunin

@Jayesh console.assert () iyi uygulama üzerinde genişletebilir, bir örnek gönderebilir misiniz?
Christopher Francisco

168

Louis'in cevabı harika, ama özlü bir şekilde özetlemeye çalışacağımı düşündüm:

Bang operatörü derleyiciye, aksi takdirde talep edebileceği "null değil" kısıtlamasını geçici olarak gevşetmesini söyler. Derleyiciye şöyle diyor: "Geliştirici olarak, bu değişkenin şu anda boş olamayacağını sizden daha iyi biliyorum".


85
Sonra, geliştirici olarak, berbat ettin.
Mike Chamberlain

9
Veya derleyici olarak dağılmıştır. Yapıcı bir özelliği başlatmaz, ancak bir yaşam döngüsü kancası yapar ve derleyici bunu tanımıyorsa.
Mukus

26
Bu TS derleyicisinin sorumluluğu değildir. Diğer bazı dillerden (ör. C #) farklı olarak, JS (ve dolayısıyla TS), değişkenlerin kullanılmadan önce başlatılmasını talep etmez. Veya başka bir şekilde bakmak gerekirse, JS'de bildirilen varveya letüstü kapalı olarak başlatılan tüm değişkenler undefined. Ayrıca, sınıf örneği özellikleri bu şekilde bildirilebilir, bu class C { constructor() { this.myVar = undefined; } }nedenle tamamen yasaldır. Son olarak, yaşam döngüsü kancaları çerçeveye bağlıdır; örneğin Açısal ve Tepki bunları farklı şekilde uygular. Bu yüzden TS derleyicisinin onlar hakkında akıl yürütmesi beklenemez.
Mike Chamberlain

1
TS'de kontrol akışına dayalı tip analizinin mükemmelliğini göz önünde bulundurarak patlama operatörü için geçerli bir kullanım durumu var mı?
Eugene Karataev

1
@EugeneKarataev Evet, çerçeveler genellikle kendi içindeki değişkenleri başlatır ve ts kontrol akış analizi onu yakalayamaz. Kullanımı kesinlikle azalır, ancak ihtiyacınız olan örneklerle karşılaşırsınız.
arg20
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.