2017-02-16 19 views
59

Patrząc na źródłowego reguły tslint, natknąłem się następującym stwierdzeniem:W Maszynopisie, co to jest! (wykrzyknik/bang) operator podczas dereferencji członka?

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

zauważy operatora ! po node.parent. Ciekawy!

Po raz pierwszy spróbowałem skompilować plik lokalnie z moją aktualnie zainstalowaną wersją TS (1.5.3). Uzyskany błąd wskazał na dokładnym położeniem hukiem:

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

Następny uaktualnieniu do najnowszych TS (2.1.6), które skompilowane go bez problemu. Wydaje się, że jest to cecha TS 2.x. Ale transpilation zignorował huk całkowicie, w wyniku następującej JS:

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

My Google fu jak dotąd nie udało mi.

Co to jest operator wykrzyknika TS i jak to działa?

Odpowiedz

100

To jest niezerowy operator asercji. To jest sposób, aby powiedzieć kompilatorowi "to wyrażenie nie może być tutaj, więc nie narzekaj na możliwość, że jest to null lub undefined." Czasami sprawdzanie typu nie jest w stanie dokonać tego samego określenia.

To jest wyjaśnione here:

Nowy operator wyrażenie ! post-fix może być wykorzystane do stwierdzenia, że ​​jego argument jest niezerowe i non-undefined w kontekstach, gdzie kontroler typu jest w stanie stwierdzić, że fakt. W szczególności operacja x! generuje wartość typu x z wykluczeniem null i undefined. Podobnie jak w przypadku asercji typu <T>x i x as T, niezerowy operator asercji ! jest po prostu usuwany z emitowanego kodu JavaScript.

Uważam, że użycie terminu "aservice" jest nieco mylące w tym wyjaśnieniu. Jest to "potwierdzenie" w tym sensie, że programista twierdzi, że jest to, nie w tym sensie, że test ma zostać wykonany. Ostatni wiersz rzeczywiście wskazuje, że nie powoduje to emisji kodu JavaScript.

+8

Dobre wezwanie na temat niejednoznaczności "twierdzącej". – estus

+4

Dobre wyjaśnienie. Uważam, że dobrą praktyką jest zrobienie 'console.assert()' na danej zmiennej przed dodaniem '!' Po niej. Ponieważ add '!' Mówi kompilatorowi, aby ignorował sprawdzanie wartości NULL, kompiluje się on do noop w javascript. Więc jeśli nie masz pewności, że zmienna ma wartość inną niż null, lepiej wykonać jawną kontrolę assert. – Jayesh

19

odpowiedź Louis' jest super, ale myślałem, że chciałbym spróbować podsumować krótko:

Operator huk informuje kompilator, aby tymczasowo rozluźnić «zerowy» nie ograniczenie, że może inaczej popyt. Mówi do kompilatora: "Jako programista wiem lepiej niż ty, że ta zmienna nie może być teraz pusta".