C'è qualche svantaggio nell'usare .tsx invece di .ts tutte le volte in dattiloscritto?


118

Ho appena iniziato a lavorare su un progetto React con TypeScript e mi chiedo cosa devo fare con i normali file di classe? Dovrei usare .tsor .tsxfile e quindi non ho trovato alcun motivo per non usare .tsxfile tutte le volte anche quando non è un progetto React!

C'è qualche motivo o situazione specifica per cui non dovremmo usare i .tsxfile? se no, perché il team di TypeScript aggiunge una nuova estensione?

Risposte:


145

Puoi usare tsxinvece che tscon pochissima differenza. tsxovviamente consente l'uso di jsxtag all'interno del dattiloscritto, ma questo introduce alcune ambiguità di analisi che rendono tsx leggermente diverso. Nella mia esperienza queste differenze non sono molto grandi:

Le asserzioni di tipo con <>non funzionano poiché questo è il marcatore per un tag jsx.

Typescript ha due sintassi per le asserzioni di tipo. Entrambi fanno la stessa identica cosa ma uno è utilizzabile in tsx, l'altro no:

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

Vorrei usare asal posto di <>in tsfile e per la coerenza. asè stato effettivamente introdotto in Typescript perché <>non era utilizzabile intsx

Le funzioni freccia generiche senza vincoli non vengono analizzate correttamente

La funzione freccia sotto va bene in tsma un errore in tsxcome <T>viene interpretato come l'inizio di un tag intsx

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

Puoi aggirare questo problema aggiungendo un vincolo o non usando una funzione freccia:

 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

Anche se puoi usare tsx invece di ts, ti consiglio di non farlo. Convention è una cosa potente, la gente associa tsxcon jsxe probabilmente saranno sorpresi non si dispone di nessun jsxtag, migliore sorpresa mastio sviluppatore al minimo.

Sebbene le ambiguità di cui sopra (sebbene probabilmente non un elenco completo) non siano grandi, probabilmente hanno giocato un ruolo importante nella decisione di utilizzare un'estensione di file dedicata per la nuova sintassi al fine di mantenere i tsfile compatibili con le versioni precedenti.


mi chiedo se i segni di asserzione del tipo <> vadano sempre prima dell'oggetto, ho visto un codice come produce <IRootStoreStateDeprecated> () e mi sono chiesto se anche questa fosse un'asserzione di tipo
Mr-Programs

1
@ Mr-Programmi domanda diversa, ma questa non è un'asserzione di tipo che è un elenco di argomenti di tipo generico. gli argomenti di tipo generico vengono dopo un identificatore e prima di un in (cui un tag JSX non può apparire, quindi non c'è ambiguità.
Titian Cernicova-Dragomir

61

È una specie di convenzione da usare xalla fine quando JavaScript è in JSX Harmonymodalità. Cioè, quando questo è valido:

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

Tuttavia, l'estensione del file non ha molta importanza, a condizione che i pre-processori siano a conoscenza della tua decisione (browserify o webpack). Io, per esempio, uso .jsper tutti i miei JavaScript, anche quando sono React. Lo stesso vale per tipografico, ts/tsx.

MODIFICARE

Ora, consiglio vivamente di utilizzare JSX per Javascript con sintassi React e TSX per TypeScript con React perché la maggior parte degli editor / IDE utilizzerà l'estensione per abilitare o meno la sintassi React. È anche considerato più espressivo.


9
"Lo stesso vale per TypeScript" - questo non è proprio vero, la maggior parte di questa risposta è specifica per JavaScript e non è proprio una buona risposta alla domanda originale su tse tsx. In TypeScript il compilatore abilita solo la sintassi JSX nei .tsxfile, perché la sintassi crea alcune ambiguità con la sintassi TS (come la <>sintassi delle asserzioni), per risolvere questo problema il compilatore fa ipotesi diverse in un tsxfile rispetto a un tsfile. Vedi la risposta di Tiziano Cernicova-Dragomir.
Aaron Beall

6

Il motivo per cui è stata introdotta l'estensione .jsx è che JSX è un'estensione della sintassi JS e quindi i file .jsx non contengono JavaScript valido.

TypeScript segue la stessa convenzione introducendo estensioni .ts e .tsx. Una differenza pratica è che .tsx non consente <Type>asserzioni di tipo perché la sintassi è in conflitto con i tag JSX. as Typeassertions è stata introdotta in sostituzione <Type>e considerata una scelta preferita per motivi di coerenza sia in .ts che in .tsx. Nel caso in cui il codice da .ts venga utilizzato nel file .tsx, <Type>dovrà essere corretto.

L'uso dell'estensione .tsx implica che un modulo è correlato a React e utilizza la sintassi JSX. In caso contrario, l'estensione potrebbe dare false impressioni sul contenuto del modulo e sul ruolo nel progetto, questo è l'argomento contro l'utilizzo dell'estensione .tsx per impostazione predefinita.

D'altra parte, se un file è correlato a React e ha buone probabilità di contenere JSX ad un certo punto, può essere chiamato .tsx dall'inizio per evitare di rinominare in seguito.

Ad esempio, le funzioni di utilità che vengono utilizzate insieme ai componenti React possono coinvolgere JSX in qualsiasi momento e quindi possono essere tranquillamente utilizzati nomi .tsx, mentre la struttura del codice Redux non dovrebbe utilizzare direttamente i componenti React, può essere utilizzata e testata separatamente da React e può utilizzare nomi .ts.


4

Credo che con i file .tsx potresti usare tutto il codice JSX (JavaScript XML). Mentre nel file .ts puoi usare solo solo dattiloscritto.


2

.tsi file hanno una <AngleBracket>sintassi di asserzione del tipo che è in conflitto con la grammatica JSX. Al fine di evitare di rompere un sacco di gente, che usiamo .tsxper JSX, e ha aggiunto la foo as Barsintassi che è consentito in entrambi .tse .tsxfile.

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

E l'altro è l'as-sintassi:

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

Possiamo usare .ts con as-syntaxma <string>someValueè fantastico!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.