Czy jest jakaś wada używania .tsx zamiast .ts przez cały czas w maszynie?

118

Po prostu zaczynam pracę nad projektem Reacta z TypeScript i zadaję sobie pytanie, co powinienem zrobić ze zwykłymi plikami klas? Powinienem używać .tsor .tsxfiles, a potem nie mogłem znaleźć żadnego powodu, aby nie używać .tsxfile przez cały czas, nawet jeśli nie jest to projekt React!

Czy jest jakiś powód lub konkretna sytuacja, w której nie powinniśmy używać .tsxplików? jeśli nie, to dlaczego zespół TypeScript dodał zupełnie nowe rozszerzenie?

Ostad
źródło

Odpowiedzi:

146

Możesz użyć tsxzamiast tsz bardzo małą różnicą. tsxoczywiście pozwala na użycie jsxznaczników wewnątrz maszynopisu, ale wprowadza to pewne niejednoznaczności podczas analizowania, które powodują, że tsx nieco się różni. Z mojego doświadczenia wynika, że ​​różnice te nie są zbyt duże:

<>Asercje typu z nie działają, ponieważ jest to znacznik dla tagu jsx.

Typescript ma dwie składnie dla asercji typu. Obaj robią dokładnie to samo, ale jeden jest użyteczny w tsx, a drugi nie:

let a: any;
let s = a as string // ok in tsx and ts
let s2 = <string>a // only valid in ts

Używałbym aszamiast <>w tsplikach, aby zachować spójność. aszostał faktycznie wprowadzony w Typescript, ponieważ <>nie był używany wtsx

Ogólne funkcje strzałkowe bez ograniczeń nie są poprawnie analizowane

Funkcja strzałka poniżej jest OK ts, ale błąd w tsxjak <T>jest interpretowana jako początek znacznika wtsx

 const fn = <T>(a: T) => a

Możesz to obejść, dodając ograniczenie lub nie używając funkcji strzałkowej:

 const fn = <T extends any>(a: T) => a
 const fn = <T,>(a: T) => a // this also works but looks weird IMO
 const fn = function<T>(a: T) { return a;}

Uwaga

Chociaż możesz użyć tsx zamiast ts, odradzałbym to. Konwencja jest potężną rzeczą, ludzie kojarzą tsxz jsxi będzie prawdopodobnie zaskoczony, że nie mają żadnych jsxznaczników, najlepsze keep programisty niespodziankę do minimum.

Chociaż powyższe niejasności (chociaż prawdopodobnie nie jest to pełna lista) nie są duże, prawdopodobnie odegrały dużą rolę w decyzji o użyciu dedykowanego rozszerzenia pliku dla nowej składni w celu zachowania tskompatybilności wstecznej plików.

Titian Cernicova-Dragomir
źródło
zastanawiam się, czy znaki asercji typu <> zawsze występują przed obiektem, widziałem kod, taki jak create <IRootStoreStateDeprecated> () i zastanawiałem się, czy to też było potwierdzenie typu
Mr-Programs
1
@ Mr-Programs inne pytanie, ale to nie jest asercja typu, która jest listą argumentów typu ogólnego. argumenty typu ogólnego pojawiają się po identyfikatorze i przed (znacznikiem JSX, który nie może się pojawić, więc nie ma niejednoznaczności.
Titian Cernicova-Dragomir
61

To rodzaj konwencji, której należy używać xna końcu, gdy JavaScript jest w JSX Harmonytrybie. To znaczy, kiedy jest to ważne:

doSomething(<div>My div</div>);

Jednak rozszerzenie pliku tak naprawdę nie ma znaczenia, o ile preprocesory są świadome Twojej decyzji (browserify lub webpack). Ja, na przykład, używam .jswszystkich moich JavaScript, nawet jeśli są to React. To samo dotyczy maszynopis, ts/tsx.

EDYTOWAĆ

Teraz zdecydowanie polecam używanie JSX dla Javascript ze składnią React i TSX dla TypeScript z React, ponieważ większość edytorów / IDE będzie używać rozszerzenia, aby włączyć lub nie składnię React. Uważa się również, że jest bardziej wyrazisty.

André Pena
źródło
9
„To samo dotyczy TypeScript” - to nieprawda, większość tej odpowiedzi dotyczy JavaScript i nie jest dobrą odpowiedzią na pierwotne pytanie dotyczące tsi tsx. W TypeScript kompilator włącza tylko składnię JSX w .tsxplikach, ponieważ składnia stwarza pewną niejednoznaczność ze składnią TS (taką jak <>składnia asercji), aby rozwiązać ten problem, kompilator przyjmuje inne założenia w tsxpliku, a nie w tspliku.Zobacz odpowiedź Titian Cernicova-Dragomir.
Aaron Beall,
7

Powodem wprowadzenia rozszerzenia .jsx jest to, że JSX jest rozszerzeniem składni JS, a zatem pliki .jsx nie zawierają prawidłowego JavaScript.

TypeScript stosuje tę samą konwencję, wprowadzając rozszerzenia .ts i .tsx. Praktyczna różnica polega na tym, że .tsx nie zezwala na <Type>asercje typu, ponieważ składnia jest w konflikcie ze znacznikami JSX. as Typeasercje zostały wprowadzone jako zamiennik <Type>i uznawane za preferowany wybór ze względu na spójność zarówno w .ts, jak i .tsx. Jeśli kod z .ts jest używany w pliku .tsx, <Type>będzie musiał zostać naprawiony.

Użycie rozszerzenia .tsx oznacza, że ​​moduł jest powiązany z Reactem i używa składni JSX. W przeciwnym razie rozszerzenie może dawać fałszywe wrażenie na temat zawartości modułu i roli w projekcie, jest to argument przeciwko domyślnemu używaniu rozszerzenia .tsx.

Z drugiej strony, jeśli plik jest powiązany z Reactem i istnieje duże prawdopodobieństwo, że w pewnym momencie będzie zawierał JSX, można go nazwać od początku jako .tsx, aby uniknąć późniejszej zmiany nazwy.

Na przykład funkcje narzędziowe, które są używane razem z komponentami React, mogą w dowolnym momencie obejmować JSX i dlatego mogą bezpiecznie używać nazw .tsx, podczas gdy struktura kodu Redux nie powinna bezpośrednio wykorzystywać komponentów , mogą być używane i testowane niezależnie od React i mogą używać nazw .ts.

Estus Flask
źródło
4

Wierzę, że z plikami .tsx można użyć całego kodu JSX (JavaScript XML). Podczas gdy w pliku .ts możesz używać tylko maszynopisu.

theITvideos
źródło
2

.tspliki mają <AngleBracket>składnię asercji typu, która jest sprzeczna z gramatyką JSX. Aby uniknąć rozbijania mnóstwa ludzi, używamy .tsxJSX i dodaliśmy foo as Barskładnię, która jest dozwolona w obu plikach .tsi .tsx.

let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

A drugi to składnia as:

let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

Możemy używać .ts z, as-syntaxale <string>someValuejest super!

Arjun Kava
źródło