Có bất kỳ nhược điểm nào khi sử dụng .tsx thay vì .ts mọi lúc trong bảng chữ không?


118

Tôi vừa mới bắt đầu làm việc trên một dự án React với TypeScript và tự hỏi bản thân mình nên làm gì với các tệp lớp thông thường? Tôi có nên sử dụng .tshoặc.tsx tệp và sau đó tôi không tìm thấy lý do gì để không sử dụng .tsxtệp mọi lúc ngay cả khi nó không phải là một dự án React!

Có bất kỳ lý do hoặc tình huống cụ thể nào mà chúng ta không nên sử dụng .tsxtệp không? nếu không, tại sao nhóm TypeScript lại thêm toàn bộ phần mở rộng mới?

Câu trả lời:


145

Bạn có thể sử dụng tsxthay thế tsvới rất ít sự khác biệt. tsxrõ ràng là cho phép sử dụng các jsxthẻ bên trong bảng chữ, nhưng điều này dẫn đến một số mơ hồ về phân tích cú pháp khiến tsx hơi khác một chút. Theo kinh nghiệm của tôi, những khác biệt này không lớn lắm:

<>Nhập các xác nhận không hoạt động vì đó là điểm đánh dấu cho thẻ jsx.

Typecript có hai cú pháp cho các xác nhận kiểu. Cả hai đều làm điều tương tự nhưng một cái có thể sử dụng được trong tsx cái kia thì không:

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

Tôi cũng sẽ sử dụng asthay vì <>trong tscác tệp để nhất quán. asthực sự đã được giới thiệu trong Typecript vì <>không thể sử dụng được trongtsx

Các hàm mũi tên chung không có ràng buộc không được phân tích cú pháp chính xác

Mũi tên chức năng bên dưới là ok trong tsnhưng một lỗi trong tsxkhi <T>được hiểu như là sự khởi đầu của một thẻ trongtsx

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

Bạn có thể giải quyết vấn đề này bằng cách thêm một ràng buộc hoặc không sử dụng hàm mũi tên:

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

Ghi chú

Mặc dù bạn có thể sử dụng tsx thay vì ts, nhưng tôi khuyên bạn không nên sử dụng nó. Công ước là một điều mạnh mẽ, người ta liên tưởng tsxvới jsxvà có lẽ sẽ ngạc nhiên bạn không có bất kỳ jsxthẻ, tốt nhất nhà phát triển giữ sự ngạc nhiên đến mức tối thiểu.

Mặc dù những mơ hồ ở trên (mặc dù có lẽ không phải là danh sách đầy đủ) không lớn nhưng có lẽ chúng đã đóng một vai trò quan trọng trong quyết định sử dụng phần mở rộng tệp chuyên dụng cho cú pháp mới để giữ cho tstệp tương thích ngược.


ngạc nhiên nếu loại khẳng định <> dấu hiệu luôn đi trước các đối tượng, tôi thấy một số mã như sản phẩm <IRootStoreStateDeprecated> () và tự hỏi nếu điều này là một typeassertion quá
Mr-Chương

1
@ Mr-Chương trình câu hỏi khác, nhưng đó không phải là một khẳng định kiểu mà là một danh sách đối số kiểu chung. các đối số kiểu chung xuất hiện sau một số nhận dạng và trước một (nơi thẻ JSX không thể xuất hiện để không có sự mơ hồ.
Titian Cernicova-Dragomir

61

xCuối cùng , đó là một quy ước để sử dụng khi JavaScript của bạn ở JSX Harmonychế độ. Đó là, khi điều này hợp lệ:

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

Tuy nhiên, phần mở rộng tệp của bạn không thực sự quan trọng, miễn là bộ xử lý trước của bạn biết về quyết định của bạn (duyệt qua hoặc gói web). Tôi, vì một, sử dụng .jscho tất cả JavaScript của tôi, ngay cả khi chúng là React. Điều tương tự cũng áp dụng cho TypeScript , ts/tsx.

BIÊN TẬP

Bây giờ, tôi thực sự khuyên bạn nên sử dụng JSX cho Javascript với cú pháp React và TSX cho TypeScript với React vì hầu hết các trình soạn thảo / IDE sẽ sử dụng phần mở rộng để kích hoạt hoặc không kích hoạt cú pháp React. Nó cũng được coi là nó để thể hiện nhiều hơn.


9
"Điều tương tự cũng áp dụng cho TypeScript" - điều này không thực sự đúng, hầu hết câu trả lời này là dành riêng cho JavaScript và không thực sự là một câu trả lời tốt cho câu hỏi ban đầu về tstsx. Trong TypeScript, trình biên dịch chỉ kích hoạt cú pháp JSX trong .tsxtệp, bởi vì cú pháp tạo ra một số mơ hồ với cú pháp TS (chẳng hạn như <>cú pháp xác nhận), để giải quyết điều này, trình biên dịch đưa ra các giả định khác nhau trong tsxtệp chứ không phải tstệp. Hãy xem câu trả lời của Titian Cernicova-Dragomir.
Aaron Beall

6

Lý do tại sao phần mở rộng .jsx được giới thiệu là JSX là phần mở rộng của cú pháp JS và do đó các tệp .jsx không chứa JavaScript hợp lệ.

TypeScript tuân theo quy ước tương tự bằng cách giới thiệu các phần mở rộng .ts và .tsx. Một sự khác biệt thực tế là .tsx không cho phép <Type>xác nhận kiểu vì cú pháp xung đột với các thẻ JSX. as Typecác xác nhận đã được giới thiệu để thay thế <Type>và được coi là lựa chọn ưu tiên vì lý do nhất quán trong cả .ts và .tsx. Trong trường hợp mã từ .ts được sử dụng trong tệp .tsx, <Type>sẽ cần được sửa.

Việc sử dụng phần mở rộng .tsx ngụ ý rằng một mô-đun có liên quan đến React và sử dụng cú pháp JSX. Trong trường hợp không, tiện ích mở rộng có thể tạo ấn tượng sai về nội dung mô-đun và vai trò trong dự án, đây là lý lẽ chống lại việc sử dụng tiện ích mở rộng .tsx theo mặc định.

Mặt khác, nếu một tệp có liên quan đến React và có nhiều khả năng chứa JSX tại một thời điểm nào đó, thì nó có thể được đặt tên là .tsx ngay từ đầu để tránh đổi tên sau này.

Ví dụ: các hàm tiện ích được sử dụng cùng với các thành phần React có thể liên quan đến JSX tại bất kỳ thời điểm nào và do đó có thể sử dụng tên .tsx một cách an toàn, trong khi cấu trúc mã Redux không được sử dụng trực tiếp các thành phần React, có thể được sử dụng và kiểm tra ngoài React và có thể sử dụng tên .ts.


4

Tôi tin rằng với các tệp .tsx, bạn có thể sử dụng tất cả mã JSX (JavaScript XML). Trong khi đó trong tệp .ts, bạn chỉ có thể sử dụng chỉ bảng chữ.


2

.tstệp có <AngleBracket>cú pháp xác nhận kiểu xung đột với ngữ pháp JSX. Để tránh .tsxlàm phiền nhiều người, chúng tôi sử dụng JSX và thêm foo as Barcú pháp được phép trong cả tệp .ts.tsxtệp.

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

Và cái kia là cú pháp as:

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

Chúng ta có thể sử dụng .ts với as-syntaxnhưng <string>someValuerất tuyệt!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.