Apakah ada sisi negatif untuk menggunakan .tsx daripada .ts sepanjang waktu dalam skrip ketikan?

118

Saya baru saja mulai mengerjakan proyek React dengan TypeScript dan bertanya pada diri sendiri apa yang harus saya lakukan dengan file kelas biasa? Haruskah saya menggunakan .tsatau .tsxfile dan kemudian saya tidak dapat menemukan alasan untuk tidak menggunakan .tsxfile sepanjang waktu bahkan ketika itu bukan proyek React!

Apakah ada alasan atau situasi khusus yang kami tidak boleh menggunakan .tsxfile? jika tidak, mengapa tim TypeScript menambahkan ekstensi baru?

Ostad
sumber

Jawaban:

145

Anda dapat menggunakan tsxalih-alih tsdengan sedikit perbedaan. tsxjelas memungkinkan penggunaan jsxtag di dalam skrip ketikan, tetapi ini memperkenalkan beberapa ambiguitas penguraian yang membuat tsx sedikit berbeda. Menurut pengalaman saya, perbedaan ini tidak terlalu besar:

Ketik pernyataan dengan <>tidak berfungsi karena itu adalah penanda untuk tag jsx.

Ketik memiliki dua sintaks untuk pernyataan tipe. Keduanya melakukan hal yang persis sama tetapi yang satu dapat digunakan di tsx, yang lainnya tidak:

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

Saya akan menggunakan asalih-alih <>dalam tsfile juga untuk konsistensi. assebenarnya diperkenalkan di Typecript karena <>tidak dapat digunakan ditsx

Fungsi panah umum tanpa batasan tidak diurai dengan benar

Fungsi panah di bawah ini baik-baik saja tstetapi kesalahan dalam tsxas <T>ditafsirkan sebagai awal dari tag ditsx

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

Anda bisa menyiasatinya dengan menambahkan batasan atau tidak menggunakan fungsi panah:

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

Catatan

Meskipun Anda dapat menggunakan tsx daripada ts, saya akan merekomendasikan untuk tidak melakukannya. Konvensi adalah hal yang kuat, orang-orang berasosiasi tsxdengan jsxdan mungkin akan terkejut Anda tidak memiliki jsxtag apa pun , sebaiknya jaga agar kejutan pengembang seminimal mungkin.

Sementara ambiguitas di atas (meskipun mungkin bukan daftar lengkap) tidak besar, mereka mungkin memainkan peran besar dalam keputusan untuk menggunakan ekstensi file khusus untuk sintaks baru agar tsfile tetap kompatibel.

Titian Cernicova-Dragomir
sumber
bertanya-tanya apakah tanda pernyataan tipe <> selalu berada sebelum objek, saya melihat beberapa kode seperti menghasilkan <IRootStoreStateDeprecated> () dan bertanya-tanya apakah ini juga jenis pernyataan
Mr-Program
1
@ Mr-Program pertanyaan yang berbeda, tapi itu bukan pernyataan tipe yang merupakan daftar argumen tipe generik. Argumen tipe umum muncul setelah pengenal dan sebelum di (mana tag JSX tidak bisa muncul sehingga tidak ada ambiguitas.
Titian Cernicova-Dragomir
61

Ini semacam konvensi untuk digunakan xpada akhirnya saat JavaScript Anda dalam JSX Harmonymode. Artinya, saat ini valid:

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

Namun, ekstensi file Anda tidak terlalu penting, selama pra-pemroses Anda mengetahui keputusan Anda (browserify atau webpack). Saya, untuk satu, menggunakan .jsuntuk semua JavaScript saya, bahkan ketika mereka adalah React. Hal yang sama berlaku untuk TypeScript ts/tsx,.

EDIT

Sekarang, saya sangat merekomendasikan menggunakan JSX untuk Javascript dengan sintaks React dan TSX untuk TypeScript dengan React karena sebagian besar editor / IDE akan menggunakan ekstensi untuk mengaktifkan atau tidak sintaks React. Itu juga menganggapnya lebih ekspresif.

André Pena
sumber
9
"Hal yang sama berlaku untuk TypeScript" - ini tidak benar, sebagian besar jawaban ini khusus untuk JavaScript dan bukan jawaban yang benar-benar bagus untuk pertanyaan asli tentang tsdan tsx. Dalam TypeScript, kompilator hanya mengaktifkan sintaks JSX dalam .tsxfile, karena sintaks tersebut membuat beberapa ambiguitas dengan sintaks TS (seperti <>sintaks pernyataan), untuk mengatasi ini kompilator membuat asumsi yang berbeda dalam tsxfile dibandingkan dengan tsfile. Lihat jawaban Titian Cernicova-Dragomir.
Aaron Beall
6

Alasan mengapa ekstensi .jsx diperkenalkan adalah karena JSX merupakan ekstensi dari sintaks JS sehingga file .jsx tidak berisi JavaScript yang valid.

TypeScript mengikuti konvensi yang sama dengan memperkenalkan ekstensi .ts dan .tsx. Perbedaan praktisnya adalah bahwa .tsx tidak mengizinkan <Type>pernyataan tipe karena sintaksnya bertentangan dengan tag JSX. as Typepernyataan diperkenalkan sebagai pengganti <Type>dan dianggap sebagai pilihan yang lebih disukai untuk alasan konsistensi di kedua .ts dan .tsx. Jika kode dari .ts digunakan dalam file .tsx, <Type>perlu diperbaiki.

Penggunaan ekstensi .tsx menyiratkan bahwa modul terkait dengan React dan menggunakan sintaks JSX. Jika tidak, ekstensi dapat memberikan kesan yang salah tentang konten modul dan peran dalam proyek, ini adalah argumen yang melarang penggunaan ekstensi .tsx secara default.

Di sisi lain, jika sebuah file terkait dengan React dan memiliki peluang bagus untuk mengandung JSX di beberapa titik, itu dapat dinamai sebagai .tsx dari awal untuk menghindari penggantian nama nanti.

Misalnya, fungsi utilitas yang digunakan bersama dengan komponen React dapat melibatkan JSX di titik mana pun dan dengan demikian dapat dengan aman menggunakan nama .tsx, sementara struktur kode Redux tidak seharusnya menggunakan komponen React secara langsung, dapat digunakan dan diuji selain dari React dan dapat menggunakan nama .ts.

Estus Flask
sumber
4

Saya percaya dengan file .tsx Anda bisa menggunakan semua kode JSX (JavaScript XML). Sedangkan pada file .ts hanya bisa menggunakan ketikan saja.

theITvideos
sumber
2

.tsfile memiliki <AngleBracket>sintaks pernyataan tipe yang bertentangan dengan tata bahasa JSX. Untuk menghindari kerusakan banyak orang, kami menggunakan .tsxJSX, dan menambahkan foo as Barsintaks yang diizinkan di file .tsdan .tsx.

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

Dan yang lainnya adalah as-sintaks:

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

Kita bisa menggunakan .ts dengan as-syntaxtapi <string>someValuekeren!

Arjun Kava
sumber