Existe alguma desvantagem em usar .tsx em vez de .ts todas as vezes no texto datilografado?

118

Acabei de começar a trabalhar em um projeto React com TypeScript e me pergunto o que devo fazer com arquivos de classe regulares? Devo usar .tsou .tsxarquivos e não encontrei motivo para não usar o .tsxarquivo todas as vezes, mesmo quando não é um projeto React!

Existe algum motivo ou situação específica para que não devamos usar .tsxarquivos? se não, por que a equipe do TypeScript adiciona uma extensão totalmente nova?

Ostad
fonte

Respostas:

145

Você pode usar em tsxvez de tscom muito pouca diferença. tsxobviamente permite o uso de jsxtags dentro do typescript, mas isso introduz algumas ambigüidades de análise que tornam o tsx ligeiramente diferente. Na minha experiência, essas diferenças não são muito grandes:

As afirmações de tipo com <>não funcionam, pois esse é o marcador para uma tag jsx.

O typescript tem duas sintaxes para asserções de tipo. Ambos fazem exatamente a mesma coisa, mas um é utilizável em tsx e o outro não é:

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

Eu usaria em asvez de <>em tsarquivos também para consistência. asfoi realmente introduzido no Typescript porque <>não era utilizável emtsx

As funções genéricas das setas sem restrições não são analisadas corretamente

A função de seta abaixo é ok em tsmas um erro em tsxcomo <T>é interpretado como o início de uma tag emtsx

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

Você pode contornar isso adicionando uma restrição ou não usando uma função de seta:

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

Nota

Embora você possa usar tsx em vez de ts, eu não recomendo. Convenção é uma coisa poderosa, as pessoas associam tsxcom jsxe provavelmente será surpreendido você não tem nenhum jsxtags, melhor surpresa desenvolvedor reduzir ao mínimo indispensável.

Embora as ambigüidades acima (embora provavelmente não sejam uma lista completa) não sejam grandes, elas provavelmente desempenharam um grande papel na decisão de usar uma extensão de arquivo dedicada para a nova sintaxe a fim de manter os tsarquivos compatíveis com versões anteriores.

Ticiano Cernicova-Dragomir
fonte
me pergunto se os sinais de asserção de tipo <> sempre vêm antes do objeto, eu vi algum código como produzir <IRootStoreStateDeprecated> () e me perguntei se isso também era uma afirmação de tipo
Mr-Programs
1
@ Mr-Programs pergunta diferente, mas isso não é uma afirmação de tipo que é uma lista de argumentos de tipo genérico. os argumentos de tipo genérico vêm depois de um identificador e antes de um em (que uma tag JSX não pode aparecer, portanto não há ambigüidade.
Ticiano Cernicova-Dragomir
61

É uma espécie de convenção para usar xno final, quando o JavaScript está no JSX Harmonymodo. Ou seja, quando for válido:

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

No entanto, a extensão do seu arquivo não importa, desde que seus pré-processadores estejam cientes de sua decisão (browserify ou webpack). Eu, por exemplo, uso .jspara todo o meu JavaScript, mesmo quando eles são React. O mesmo se aplica ao TypeScript ts/tsx,.

EDITAR

Agora, eu recomendo fortemente o uso de JSX para Javascript com sintaxe React e TSX para TypeScript com React porque a maioria dos editores / IDEs usará a extensão para habilitar ou não a sintaxe React. É também considerá-lo mais expressivo.

André Pena
fonte
9
"O mesmo se aplica ao TypeScript" - isso não é realmente verdade, a maior parte desta resposta é específica para JavaScript e não é realmente uma boa resposta à pergunta original sobre tse tsx. No TypeScript, o compilador só habilita a sintaxe JSX em .tsxarquivos, porque a sintaxe cria alguma ambigüidade com a sintaxe TS (como a <>sintaxe de asserção). Para resolver isso, o compilador faz suposições diferentes em um tsxarquivo em oposição a um tsarquivo. Veja a resposta de Titian Cernicova-Dragomir.
Aaron Beall
6

O motivo pelo qual a extensão .jsx foi introduzida é que JSX é uma extensão da sintaxe JS e, portanto, os arquivos .jsx não contêm JavaScript válido.

O TypeScript segue a mesma convenção ao introduzir as extensões .ts e .tsx. Uma diferença prática é que .tsx não permite <Type>asserções de tipo porque a sintaxe está em conflito com as tags JSX. as Typeassertions foi introduzido como um substituto <Type>e considerado uma escolha preferencial por motivos de consistência em .ts e .tsx. Caso o código de .ts seja usado em arquivo .tsx, <Type>será necessário consertar.

O uso da extensão .tsx implica que um módulo está relacionado ao React e usa a sintaxe JSX. Caso contrário, a extensão pode dar uma falsa impressão sobre o conteúdo do módulo e a função no projeto, este é o argumento contra o uso da extensão .tsx por padrão.

Por outro lado, se um arquivo estiver relacionado ao React e tiver boas chances de conter JSX em algum ponto, ele pode ser nomeado como .tsx desde o início para evitar renomeá-lo posteriormente.

Por exemplo, funções utilitárias que são usadas junto com componentes React podem envolver JSX em qualquer ponto e, portanto, podem ser usadas com segurança nomes .tsx, enquanto a estrutura de código Redux não deve usar componentes React diretamente, pode ser usada e testada separadamente de React e pode usar nomes .ts.

Estus Flask
fonte
4

Eu acredito que com os arquivos .tsx você pode usar todo o código JSX (JavaScript XML). Enquanto no arquivo .ts você pode usar apenas o texto digitado.

theITvideos
fonte
2

.tsos arquivos têm uma <AngleBracket>sintaxe de asserção de tipo que entra em conflito com a gramática JSX. Para evitar quebrar uma tonelada de pessoas, usamos .tsxpara JSX, e adicionamos a foo as Barsintaxe que é permitida em ambos os arquivos .tse .tsx.

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

E a outra é a sintaxe como:

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

Podemos usar .ts com, as-syntaxmas <string>someValueé legal!

Arjun Kava
fonte