Есть ли недостатки в использовании .tsx вместо .ts постоянно в машинописном тексте?


119

Я просто начинаю работать над проектом React с TypeScript и спрашиваю себя, что мне делать с обычными файлами классов? Должен ли я использовать .tsили .tsxfiles, и тогда я не мог найти причины не использовать .tsxфайл постоянно, даже если это не проект React!

Есть ли причина или конкретная ситуация, по которой мы не должны использовать .tsxфайлы? если нет, то зачем команда TypeScript добавила совершенно новое расширение?

Ответы:


147

Вы можете использовать tsxвместо tsс очень небольшой разницей. tsxочевидно, позволяет использовать jsxтеги внутри машинописного текста, но это вносит некоторую двусмысленность при синтаксическом анализе, которая делает tsx немного другим. По моему опыту, эти различия не очень большие:

Утверждения типа с <>не работают, поскольку это маркер для тега jsx.

В Typescript есть два синтаксиса для утверждений типа. Они оба делают одно и то же, но один можно использовать в 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

Стандартные стрелочные функции без ограничений анализируются неправильно

Указанная ниже стрелочная функция работает, tsно ошибка в tsxas <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;}

Заметка

Хотя вы можете использовать tsx вместо ts, я бы не рекомендовал его. Конвенция является сильной вещью, люди ассоциируют tsxс jsxи, вероятно , будут удивлены , что вы не имеете никаких jsxтегов, лучший разработчик Keep сюрприз к минимуму.

Хотя приведенные выше неоднозначности (хотя, вероятно, не полный список) невелики, они, вероятно, сыграли большую роль в решении использовать выделенное расширение файла для нового синтаксиса, чтобы сохранить tsобратную совместимость файлов.


Интересно, всегда ли знаки типа assertion <> идут перед объектом, я видел какой-то код, например, произвести <IRootStoreStateDeprecated> (), и задавался вопросом, было ли это тоже typeassertion
Mr-Programs

1
@ Mr-Programs - другой вопрос, но это не утверждение типа, которое является списком аргументов универсального типа. Аргументы универсального типа идут после идентификатора и до, (где тег JSX не может появиться, поэтому нет двусмысленности.
Тициан Черникова-Драгомир

61

Это своего рода соглашение, которое нужно использовать xв конце, когда ваш JavaScript находится в JSX Harmonyрежиме. То есть, когда это действительно:

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

Однако расширение вашего файла на самом деле не имеет значения, если ваши препроцессоры знают о вашем решении (просмотр или веб-пакет). Я, например, использую .jsвесь свой JavaScript, даже если это React. То же относится к машинописи, ts/tsx.

РЕДАКТИРОВАТЬ

Теперь я настоятельно рекомендую использовать JSX для Javascript с синтаксисом React и TSX для TypeScript с React, потому что большинство редакторов / IDE будут использовать расширение для включения или выключения синтаксиса React. Его также считают более выразительным.


9
«То же самое применимо и к TypeScript» - это не совсем так, большая часть этого ответа специфична для JavaScript и не совсем хороший ответ на исходный вопрос об tsи tsx. В TypeScript компилятор разрешает только синтаксис JSX в .tsxфайлах, поскольку синтаксис создает некоторую неоднозначность с синтаксисом TS (например, <>синтаксис утверждения), для решения этой проблемы компилятор делает различные предположения в tsxфайле, а не в tsфайле. См. Ответ Тициана Черникова-Драгомира.
Аарон Билл

7

Причина, по которой было введено расширение .jsx, заключается в том, что JSX является расширением синтаксиса JS и, следовательно, файлы .jsx не содержат допустимого JavaScript.

TypeScript следует тому же соглашению, вводя расширения .ts и .tsx. Практическое отличие состоит в том, что .tsx не допускает <Type>утверждения типа, поскольку синтаксис конфликтует с тегами JSX. as Typeassertions были введены как замена <Type>и считались предпочтительным выбором из соображений согласованности как в .ts, так и .tsx. Если в файле .tsx используется код из .ts, <Type>его необходимо исправить.

Использование расширения .tsx подразумевает, что модуль связан с React и использует синтаксис JSX. В противном случае расширение может создать ложное впечатление о содержимом модуля и роли в проекте, это аргумент против использования расширения .tsx по умолчанию.

С другой стороны, если файл связан с React и имеет хорошие шансы содержать JSX в какой-то момент, он может с самого начала называться .tsx, чтобы избежать переименования позже.

Например, служебные функции, которые используются вместе с компонентами React, могут включать JSX в любой момент и, таким образом, могут безопасно использовать имена .tsx, в то время как структура кода Redux не должна использовать компоненты React напрямую, может использоваться и тестироваться отдельно от React и может использовать имена .ts.


4

Я считаю, что с файлами .tsx вы можете использовать весь код JSX (JavaScript XML). В то время как в файле .ts вы можете использовать только машинописный текст.


2

.tsфайлы имеют <AngleBracket>синтаксис утверждения типа, который конфликтует с грамматикой JSX. Чтобы не сломать тонну людей, мы используем .tsxJSX и добавили foo as Barсинтаксис, который разрешен как в файлах, так .tsи в .tsxфайлах.

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

А другой - as-синтаксис:

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

Мы можем использовать .ts, as-syntaxно <string>someValueэто круто!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.