Answers:
您可以使用tsx
而不是ts
几乎没有区别。tsx
显然允许jsx
在Typescript中使用标签,但这会引入一些解析歧义,使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
而不是为了保持一致性。实际上是在Typescript中引入的,因为在<>
ts
as
<>
tsx
没有约束的通用箭头函数无法正确解析
下面的箭头功能是好的ts
,但在错误tsx
的<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
标记,最好保持显影剂惊喜到最低限度。
尽管上面的歧义(尽管可能不是完整列表)并不大,但它们可能在决定使用专用文件扩展名来支持新语法以保持ts
文件向后兼容方面起了很大的作用。
(
JSX标签无法显示的位置之前出现,因此没有歧义。
x
最后,当您的JavaScript处于JSX Harmony
模式下时,这是一种约定。也就是说,当这是有效的时:
doSomething(<div>My div</div>);
但是,只要您的预处理程序知道您的决定(浏览器或webpack),文件扩展名实际上就无关紧要。我使用.js
了我所有的JavaScript,即使它们是React。TypeScript也是如此ts/tsx
。
编辑
现在,我强烈建议将JavaScript的JSX与React语法一起使用,将TSX的TypeScript与React一起使用,因为大多数编辑器/ IDE将使用扩展名来启用或不启用React语法。它也被认为更具表现力。
ts
和的原始问题的好答案tsx
。在TypeScript中,编译器仅在.tsx
文件中启用JSX语法,因为该语法与TS语法(例如,<>
断言语法)产生了一些歧义,因此,编译器在tsx
文件而非文件中做出不同的假设以解决此问题ts
。请参阅Titian Cernicova-Dragomir的答案。
引入.jsx扩展名的原因是JSX是JS语法的扩展名,因此.jsx文件不包含有效的JavaScript。
TypeScript通过引入.ts和.tsx扩展名遵循相同的约定。一个实际的区别是.tsx不允许<Type>
类型断言,因为语法与JSX标签冲突。as Type
断言是<Type>
.ts和.tsx中出于一致性原因而引入的,并被认为是首选。如果.tsx文件中使用了.ts中的代码,<Type>
则需要进行修复。
使用.tsx扩展名意味着模块与React相关并且使用JSX语法。如果没有,扩展名可能会给模块内容和项目中的角色带来错误的印象,这是默认情况下不使用.tsx扩展名的理由。
另一方面,如果文件与React相关,并且在某个时候很有可能包含JSX,则可以从一开始就将其命名为.tsx,以避免以后重命名。
例如,与React组件一起使用的实用程序函数在任何时候都可能涉及JSX,因此可以安全地使用.tsx名称,而Redux代码结构不应直接使用React组件,可以与React分开使用和测试并可以使用.ts名称。
.ts
文件具有<AngleBracket>
与JSX语法冲突的类型断言语法。为了避免造成很多.tsx
麻烦,我们使用JSX,并添加了和文件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
很酷!