Gibt es einen Nachteil bei der Verwendung von .tsx anstelle von .ts in Typoskripten?

117

Ich arbeite gerade an einem React-Projekt mit TypeScript und frage mich, was ich mit regulären Klassendateien tun soll. Sollte ich .tsoder .tsxDateien verwenden und dann konnte ich keinen Grund finden, Dateien nicht immer zu verwenden, .tsxselbst wenn es kein React-Projekt ist!

Gibt es einen Grund oder eine spezielle Situation, in der wir keine .tsxDateien verwenden sollten? Wenn nein, warum fügt das TypeScript-Team eine ganz neue Erweiterung hinzu?

Ostad
quelle

Antworten:

144

Sie können tsxstatt tsmit sehr geringem Unterschied verwenden. tsxerlaubt natürlich die Verwendung von jsxTags innerhalb von Typoskript, aber dies führt zu einigen Mehrdeutigkeiten beim Parsen, die tsx etwas anders machen. Nach meiner Erfahrung sind diese Unterschiede nicht sehr groß:

<>Typzusicherungen mit funktionieren nicht, da dies die Markierung für ein jsx-Tag ist.

Typescript verfügt über zwei Syntaxen für Typzusicherungen. Beide machen genau das Gleiche, aber einer ist in tsx verwendbar, der andere nicht:

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

Ich würde verwenden , asanstatt <>in tsder Konsistenz als auch Dateien. aswurde tatsächlich in Typescript eingeführt, weil <>es in nicht verwendbar wartsx

Generische Pfeilfunktionen ohne Einschränkung werden nicht korrekt analysiert

Die Pfeilfunktion unten ist in Ordnung, tsaber ein Fehler in tsxas <T>wird als Beginn eines Tags in interpretierttsx

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

Sie können dies umgehen, indem Sie entweder eine Einschränkung hinzufügen oder keine Pfeilfunktion verwenden:

 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;}

Hinweis

Während Sie tsx anstelle von ts verwenden können, würde ich dagegen empfehlen. Übereinkommen ist ein mächtiges Ding, assoziieren Menschen tsxmit jsxund werden wahrscheinlich überrascht sein , Sie haben noch keine jsxTags, am besten keep Entwickler Überraschung auf ein Minimum.

Obwohl die oben genannten Unklarheiten (obwohl wahrscheinlich keine vollständige Liste) nicht groß sind, spielten sie wahrscheinlich eine große Rolle bei der Entscheidung, eine dedizierte Dateierweiterung für die neue Syntax zu verwenden, um tsDateien abwärtskompatibel zu halten .

Tizian Cernicova-Dragomir
quelle
Ich frage mich, ob Zeichen für die Typzusicherung <> immer vor dem Objekt stehen. Ich habe Code wie "<IRootStoreStateDeprecated> ()" gesehen und mich gefragt, ob dies auch eine Typzusicherung ist
Mr-Programs
1
@ Mr-Programs andere Frage, aber das ist keine Typzusicherung, die eine generische Typargumentliste ist. Generische Typargumente stehen nach einem Bezeichner und vor einem, (bei dem ein JSX-Tag nicht angezeigt werden kann, sodass keine Mehrdeutigkeit besteht.
Tizian Cernicova-Dragomir
61

Es ist eine Art Konvention, die Sie xam Ende verwenden müssen, wenn sich Ihr JavaScript im JSX HarmonyModus befindet. Das heißt, wenn dies gültig ist:

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

Ihre Dateierweiterung spielt jedoch keine Rolle, solange Ihre Vorprozessoren über Ihre Entscheidung informiert sind (browserify oder webpack). Zum einen verwende ich .jsfür alle meine JavaScript, auch wenn sie reagieren. Gleiches gilt für TypeScript , ts/tsx.

BEARBEITEN

Jetzt würde ich dringend empfehlen, JSX für Javascript mit React-Syntax und TSX für TypeScript mit React zu verwenden, da die meisten Editoren / IDEs die Erweiterung verwenden, um die React-Syntax zu aktivieren oder nicht. Es wird auch als ausdrucksstärker angesehen.

André Pena
quelle
9
"Gleiches gilt für TypeScript" - dies ist nicht wirklich wahr, der größte Teil dieser Antwort ist spezifisch für JavaScript und keine wirklich gute Antwort auf die ursprüngliche Frage zu tsund tsx. In TypeScript aktiviert der Compiler nur die JSX-Syntax in .tsxDateien, da die Syntax eine gewisse Mehrdeutigkeit mit der TS-Syntax (z. B. der <>Assertionssyntax) erzeugt. Um dies zu lösen, trifft der Compiler in einer tsxDatei andere Annahmen als in einer tsDatei. Siehe die Antwort von Tizian Cernicova-Dragomir.
Aaron Beall
6

Der Grund für die Einführung der Erweiterung .jsx ist, dass JSX eine Erweiterung der JS-Syntax ist und daher .jsx-Dateien kein gültiges JavaScript enthalten.

TypeScript folgt der gleichen Konvention, indem es die Erweiterungen .ts und .tsx einführt. Ein praktischer Unterschied besteht darin, dass .tsx keine Typzusicherungen zulässt <Type>, da die Syntax mit JSX-Tags in Konflikt steht. as TypeBehauptungen wurden als Ersatz für <Type>und wurden aus Konsistenzgründen sowohl in .ts als auch in .tsx als bevorzugte Wahl eingeführt. Falls der Code aus .ts in der .tsx-Datei verwendet <Type>wird, muss er behoben werden.

Die Verwendung der Erweiterung .tsx impliziert, dass ein Modul mit React zusammenhängt und die JSX-Syntax verwendet. Falls dies nicht der Fall ist, kann die Erweiterung einen falschen Eindruck über den Modulinhalt und die Rolle im Projekt vermitteln. Dies ist das Argument gegen die standardmäßige Verwendung der Erweiterung .tsx.

Wenn eine Datei jedoch mit React zusammenhängt und gute Chancen hat, irgendwann JSX zu enthalten, kann sie von Anfang an als .tsx bezeichnet werden, um ein späteres Umbenennen zu vermeiden.

Zum Beispiel können Dienstprogrammfunktionen, die zusammen mit React-Komponenten verwendet werden, JSX an jedem Punkt einbeziehen und somit sicher .tsx-Namen verwenden, während die Redux- Codestruktur React-Komponenten nicht direkt verwenden soll, sondern außer React verwendet und getestet werden kann und kann .ts Namen verwenden.

Estus Flask
quelle
4

Ich glaube, mit den .tsx-Dateien könnten Sie den gesamten JSX-Code (JavaScript XML) verwenden. Während Sie in der .ts-Datei nur Typoskript verwenden können.

theITvideos
quelle
2

.tsDateien haben eine <AngleBracket>Typzusicherungssyntax, die mit der JSX-Grammatik in Konflikt steht. Um zu vermeiden, dass eine Menge Leute .tsxkaputt gehen , verwenden wir JSX und fügen die foo as BarSyntax hinzu, die sowohl in .tsals auch in .tsxDateien zulässig ist .

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

Und das andere ist die As-Syntax:

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

Wir können .ts mit verwenden as-syntax, <string>someValueist aber cool!

Arjun Kava
quelle