You can use tsx
instead of ts
with very little difference. tsx
obviously allows the usage of jsx
tags inside TypeScript, but this introduces some parsing ambiguities that make tsx slightly different. In my experience these differences are not very big:
Type assertions with <>
don't work as that is the marker for a jsx tag.
TypeScript has two syntaxes for type assertions. They both do the exact same thing but one is usable in tsx the other is not:
let a: any;
let s = a as string // ok in tsx and ts
let s2 = <string>a // only valid in ts
I would use as
instead of <>
in ts
files as well for consistency. as
was actually introduced in TypeScript because <>
was not usable in tsx
.
Generic arrow functions with no constraint are not parsed correctly
The arrow function below is ok in ts
but an error in tsx
as <T>
is interpreted as the start of a tag in tsx
:
const fn = <T>(a: T) => a
You can get around this either by adding a constraint or not using an arrow function:
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;}
Note
While you can use tsx
instead of ts
, I would recommend against it. Convention is a powerful thing, people associate tsx
with jsx
and will probably be surprised you don't have any jsx
tags, best keep developer surprise to a minimum.
While the ambiguities above (although probably not a complete list) are not big they probably played a big part in the decision to use a dedicated file extension for the new syntax in order to keep ts
files backward compatible.