¿Hay alguna desventaja de usar .tsx en lugar de .ts todas las veces en mecanografiado?

118

Acabo de empezar a trabajar en un proyecto de React con TypeScript y me pregunto ¿qué debo hacer con los archivos de clase normales? ¿Debo usar archivos .tso .tsxy luego no pude encontrar ninguna razón para no usar el .tsxarchivo todo el tiempo, incluso cuando no es un proyecto de React!

¿Existe alguna razón o situación específica por la que no debamos utilizar .tsxarchivos? Si no, ¿por qué el equipo de TypeScript agrega una extensión completamente nueva?

Ostad
fuente

Respuestas:

145

Puede utilizar en tsxlugar de tscon muy poca diferencia. tsxobviamente permite el uso de jsxetiquetas dentro de mecanografiado, pero esto introduce algunas ambigüedades de análisis que hacen que tsx sea ligeramente diferente. En mi experiencia, estas diferencias no son muy grandes:

Las afirmaciones de tipo con <>no funcionan, ya que ese es el marcador de una etiqueta jsx.

TypeScript tiene dos sintaxis para las afirmaciones de tipo. Ambos hacen exactamente lo mismo, pero uno se puede usar en tsx y el otro no:

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

También lo usaría en aslugar de <>en tsarchivos para mayor coherencia. asse introdujo en Typecript porque <>no se podía usar entsx

Las funciones de flecha genéricas sin restricción no se analizan correctamente

La función de la flecha de abajo está bien en tspero un error en el tsxque <T>se interpreta como el inicio de una etiqueta entsx

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

Puede evitar esto agregando una restricción o no usando una función de flecha:

 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

Si bien puede usar tsx en lugar de ts, no lo recomendaría. Convención es algo muy poderoso, la gente asocia tsxcon jsxy es probable que se sorprendió que no tiene ningún jsxetiquetas, mejor desarrollador de mantener la sorpresa al mínimo.

Si bien las ambigüedades anteriores (aunque probablemente no sea una lista completa) no son grandes, probablemente jugaron un papel importante en la decisión de usar una extensión de archivo dedicada para la nueva sintaxis a fin de mantener los tsarchivos compatibles con versiones anteriores.

Tiziano Cernicova-Dragomir
fuente
Me pregunto si los signos de afirmación de tipo <> siempre van antes del objeto, vi un código como producir <IRootStoreStateDeprecated> () y me pregunté si esto también era una afirmación de tipo
Mr-Programs
1
@ Mr-Programs es una pregunta diferente, pero esa no es una afirmación de tipo que sea una lista de argumentos de tipo genérico. Los argumentos de tipo genérico vienen después de un identificador y antes de un (donde no puede aparecer una etiqueta JSX, por lo que no hay ambigüedad.
Tiziano Cernicova-Dragomir
61

Es una especie de convención para usar xal final cuando su JavaScript está en JSX Harmonymodo. Es decir, cuando esto es válido:

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

Sin embargo, su extensión de archivo realmente no importa, siempre que sus preprocesadores estén al tanto de su decisión (browserify o webpack). Yo, por mi parte, uso .jspara todo mi JavaScript, incluso cuando son React. Lo mismo se aplica para el mecanografiado, ts/tsx.

EDITAR

Ahora, recomendaría encarecidamente usar JSX para Javascript con sintaxis de React y TSX para TypeScript con React porque la mayoría de los editores / IDE usarán la extensión para habilitar o no la sintaxis de React. También se considera más expresivo.

André Pena
fuente
9
"Lo mismo se aplica a TypeScript": esto no es realmente cierto, la mayor parte de esta respuesta es específica de JavaScript y no es realmente una buena respuesta a la pregunta original sobre tsy tsx. En TypeScript, el compilador solo habilita la sintaxis JSX en .tsxarchivos, porque la sintaxis crea cierta ambigüedad con la sintaxis de TS (como la <>sintaxis de aserción), para resolver esto, el compilador hace diferentes suposiciones en un tsxarchivo en lugar de en un tsarchivo. Vea la respuesta de Tiziano Cernicova-Dragomir.
Aaron Beall
6

La razón por la que se introdujo la extensión .jsx es que JSX es una extensión de la sintaxis JS y, por lo tanto, los archivos .jsx no contienen JavaScript válido.

TypeScript sigue la misma convención al introducir las extensiones .ts y .tsx. Una diferencia práctica es que .tsx no permite <Type>afirmaciones de tipo porque la sintaxis está en conflicto con las etiquetas JSX. as TypeLas aserciones se introdujeron como un reemplazo <Type>y se consideró una opción preferida por razones de coherencia tanto en .ts como en .tsx. En caso de que el código de .ts se utilice en el archivo .tsx, <Type>deberá corregirse .

El uso de la extensión .tsx implica que un módulo está relacionado con React y usa la sintaxis JSX. En caso de que no lo haga, la extensión puede dar una impresión falsa sobre el contenido del módulo y el rol en el proyecto, este es el argumento en contra del uso de la extensión .tsx por defecto.

Por otro lado, si un archivo está relacionado con React y tiene buenas posibilidades de contener JSX en algún momento, se puede nombrar como .tsx desde el principio para evitar cambiar el nombre más adelante.

Por ejemplo, las funciones de utilidad que se usan junto con los componentes de React pueden involucrar a JSX en cualquier punto y, por lo tanto, se pueden usar con seguridad nombres .tsx, mientras que que la estructura del código Redux no debe usar componentes de React directamente, se puede usar y probar aparte de React. y puede usar nombres .ts.

Matraz Estus
fuente
4

Creo que con los archivos .tsx podría usar todo el código JSX (JavaScript XML). Mientras que en el archivo .ts solo puede usar mecanografiado.

theITvideos
fuente
2

.tsLos archivos tienen una <AngleBracket>sintaxis de aserción de tipo que entra en conflicto con la gramática JSX. Para evitar romper a un montón de personas, usamos .tsxpara JSX y agregamos la foo as Barsintaxis que está permitida en ambos archivos .tsy .tsx.

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

Y el otro es la sintaxis as:

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

Podemos usar .ts con ¡ as-syntaxpero <string>someValuees genial!

Arjun Kava
fuente