typescriptで常に.tsではなく.tsxを使用することの欠点はありますか?


118

TypeScriptを使用してReactプロジェクトの作業を開始し、通常のクラスファイルをどうすればよいか自問しています。.tsまたは.tsxファイルを使用する必要がありますが.tsx、Reactプロジェクトではない場合でも、ファイルを常に使用しない理由を見つけることができませんでした。

.tsxファイルを使用してはならない理由または特定の状況はありますか?いいえの場合、なぜTypeScriptチームはまったく新しい拡張機能を追加するのですか?

回答:


145

あなたは使用することができますtsx代わりにtsはほとんど差が。tsx明らかにjsxtypescript内でのタグの使用を許可しますが、これにより、tsxをわずかに異なるものにする解析のあいまいさがいくつか導入されます。私の経験では、これらの違いはそれほど大きくありません。

タイプアサーション<>は、それがjsxタグのマーカーであるため機能しません。

Typescriptには、型表明のための2つの構文があります。どちらもまったく同じことを行いますが、一方はtsxで使用でき、もう一方は使用できません。

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

一貫性を保つためas<>tsファイルの代わりに使用します。as<>使用できなかったため、Typescriptで実際に導入されましたtsx

制約のない一般的な矢印関数が正しく解析されない

下の矢印機能はOKであるtsが、中に誤りtsxとして<T>タグの開始として解釈されtsx

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

これを回避するには、制約を追加するか、矢印関数を使用しません。

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

注意

tsの代わりにtsxを使用できますが、お勧めしません。条約は強力なもので、人々が関連付けるtsxjsx、おそらくあなたが任意の必要はありません驚かれることでしょうjsx最小限にタグを、最高のキープ開発者の驚き。

上記のあいまいさは(おそらく完全なリストではありませんが)大きくはありませんが、tsファイルの下位互換性を維持するために、新しい構文に専用のファイル拡張子を使用する決定に大きな役割を果たしました。


タイプアサーション<>記号が常にオブジェクトの前にあるかどうか疑問に思ったので、produce <IRootStoreStateDeprecated>()などのコードを見て、これもタイプアサーションかどうか疑問に思いました
Mr-Programs

1
@ Mr-Programsは別の質問ですが、これは一般的な型引数リストである型アサーションではありません。ジェネリック型の引数は、識別子の後、(JSXタグを表示できない場所の前にあるため、あいまいさはありません。
Titian Cernicova-Dragomir

61

これxは、JavaScriptがJSX Harmonyモードになっているときに最後に使用する規則の一種です。つまり、これが有効な場合:

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

ただし、プリプロセッサが判断(ブラウザ化またはWebパック)を認識している限り、ファイル拡張子は実際には重要ではありません。私は1 .jsつには、JavaScriptがすべてReactであっても、すべてのJavaScriptを使用します。TypeScriptにも同じことが当てはまりますts/tsx

編集

ほとんどのエディター/ IDEは拡張機能を使用してReact構文を有効にするかどうかを判断するため、React構文を使用するJavaScriptのJSXとReactを使用するTypeScriptのTSXを使用することを強くお勧めします。それはまた、より表現力があると見なされます。


9
「同じことが活字体に適用される」 -これは本当に真実ではない、この答えのほとんどはJavaScriptに固有ではなく、本当に程度元の質問に良い答えtstsx。TypeScriptでは、コンパイラーは.tsxファイル内のJSX構文のみを有効にします。これは、構文がTS構文(<>アサーション構文など)とあいまいさを生み出すため、コンパイラーはこれを解決するために、tsxファイルではなくファイル内で異なる前提を作成しtsます。Titian Cernicova-Dragomirの回答を参照してください。
アーロンビール

6

.jsx拡張子が導入された理由は、JSXがJS構文の拡張であるため、.jsxファイルに有効なJavaScriptが含まれていないためです。

TypeScriptは、.tsおよび.tsx拡張子を導入することにより、同じ規則に従います。実用的な違いは<Type>、構文がJSXタグと競合しているため、.tsxでは型のアサーションが許可されないことです。as Typeアサーションは<Type>、.tsと.tsxの両方で一貫性の理由からの代替として導入され、推奨される選択肢と見なされました。.tsのコードが.tsxファイルで使用されている場合は、<Type>修正する必要があります。

.tsx拡張子の使用は、モジュールがReactに関連し、JSX構文を使用することを意味します。そうでない場合、拡張機能はモジュールの内容とプロジェクトでの役割について誤った印象を与える可能性があります。これは、デフォルトでの.tsx拡張子の使用に対する反対です。

一方、ファイルがReactに関連していて、ある時点でJSXが含まれる可能性が高い場合は、後で名前を変更しないように、最初から.tsxという名前を付けることができます。

たとえば、Reactコンポーネントと一緒に使用されるユーティリティ関数はいつでもJSXを必要とする可能性があるため、.tsx名を安全に使用できますが、Reduxコード構造はReactコンポーネントを直接使用することは想定されていないため、Reactとは別に使用およびテストできます.ts名を使用できます。


4

.tsxファイルでは、すべてのJSX(JavaScript XML)コードを使用できると思います。一方、.tsファイルではtypescriptのみを使用できます。


2

.tsファイルには、<AngleBracket>JSX文法と競合する型アサーション構文があります。.tsx大量の人を壊さないようにするために、JSX を使用foo as Barし、.ts.tsxファイルの両方で使用できる構文を追加しました。

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

もう1つは、as-syntaxです。

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

私たちは、と.TSを使用することができas-syntaxますが<string>someValueクールです!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.