【问题标题】:Is there any downside to using .tsx instead of .ts all the times in typescript?在打字稿中一直使用 .tsx 而不是 .ts 有什么缺点吗?
【发布时间】:2016-03-17 09:27:24
【问题描述】:

我刚开始使用 TypeScript 处理一个 React 项目,并问自己应该如何处理常规类文件?我应该使用.ts.tsx 文件,然后我找不到任何理由不使用.tsx 文件,即使它不是React 项目!

是否有任何理由或特定情况我们不应该使用.tsx 文件?如果没有,为什么 TypeScript 团队要添加全新的扩展?

【问题讨论】:

标签: javascript reactjs typescript


【解决方案1】:

您可以使用tsx 代替ts,差别很小。 tsx 显然允许在 TypeScript 中使用 jsx 标签,但这会引入一些解析歧义,使 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

为了保持一致性,我也会在 ts 文件中使用 as 而不是 &lt;&gt;as 实际上是在 TypeScript 中引入的,因为 &lt;&gt;tsx 中不可用。

没有约束的通用箭头函数解析不正确

下面的箭头函数在ts 中是可以的,但是tsx 中的错误&lt;T&gt; 被解释为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,但我建议您不要这样做。约定是一个强大的东西,人们将tsxjsx 联系起来,你可能会惊讶于你没有任何jsx 标签,最好将开发人员的惊喜降到最低。

虽然上面的歧义(虽然可能不是一个完整的列表)并不大,但它们可能在决定为新语法使用专用文件扩展名以保持 ts 文件向后兼容的决定中发挥了重要作用。

【讨论】:

  • 想知道类型断言 符号是否总是在对象之前,我看到了一些像 producer() 这样的代码,想知道这是否也是类型断言
  • @Mr-Programs 不同的问题,但这不是泛型类型参数列表的类型断言。泛型类型参数位于标识符之后和 ( 之前,其中不能出现 JSX 标记,因此没有歧义。
  • React Native 中的 StyleSheet 怎么样?它也是一个 JSX 标签吗?我想创建一个仅包含和导出 StyleSheet 的仅样式文件,但我不确定是否应该将其命名为 .tsx。
【解决方案2】:

当您的 JavaScript 处于 JSX Harmony 模式时,最后使用 x 是一种约定。也就是说,当这是有效的:

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

但是,您的文件扩展名并不重要,只要您的预处理器知道您的决定(浏览器化或 webpack)。一方面,我对我所有的 JavaScript 使用 .js,即使它们是 React。这同样适用于 TypeScript,ts/tsx

编辑

现在,我强烈建议使用带有 React 语法的 Javascript 的 JSX 和带有 React 的 TypeScript 的 TSX,因为大多数编辑器/IDE 将使用扩展来启用或不启用 React 语法。它也被认为更具表现力。

【讨论】:

  • “TypeScript 也是如此”——这不是真的,这个答案大部分都是针对 JavaScript 的,并不是对关于 tstsx 的原始问题的一个很好的答案.在 TypeScript 中,编译器仅在 .tsx 文件中启用 JSX 语法,因为该语法与 TS 语法(例如 &lt;&gt; 断言语法)产生了一些歧义,为了解决这个问题,编译器在 tsx 文件中做出不同的假设而不是到ts 文件。 请参阅 Titian Cernicova-Dragomir 的回答。
【解决方案3】:

引入 .jsx 扩展名的原因是 JSX 是 JS 语法的扩展,因此 .jsx 文件不包含有效的 JavaScript。

TypeScript 遵循相同的约定,引入了 .ts 和 .tsx 扩展名。一个实际的区别是 .tsx 不允许 &lt;Type&gt; 类型断言,因为语法与 JSX 标签冲突。 as Type 断言是作为 &lt;Type&gt; 的替代品引入的,出于 .ts 和 .tsx 的一致性原因,它被认为是首选。如果 .ts 中的代码用于 .tsx 文件,则需要修复 &lt;Type&gt;

.tsx 扩展名的使用意味着模块与 React 相关并使用 JSX 语法。如果没有,扩展可能会给模块内容和项目中的角色留下错误的印象,这是反对默认使用 .tsx 扩展的论据。

另一方面,如果一个文件与 React 相关并且在某些时候很有可能包含 JSX,则可以从一开始就将其命名为 .tsx 以避免以后重命名。

例如,与 React 组件一起使用的实用程序函数可能在任何时候都涉及 JSX,因此可以安全地使用 .tsx 名称,而 Redux code structure 不应该直接使用 React 组件,可以使用和测试除了 React 并且可以使用 .ts 名称。

【讨论】:

【解决方案4】:

我相信通过 .tsx 文件,您可以使用所有 JSX (JavaScript XML) 代码。而在 .ts 文件中,您只能使用打字稿。

【讨论】:

    【解决方案5】:

    .ts 文件具有与 JSX 语法冲突的 &lt;AngleBracket&gt; 类型断言语法。为了避免破坏大量人员,我们将 .tsx 用于 JSX,并添加了 foo as Bar 语法,这在 .ts.tsx 文件中都是允许的。

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

    另一个是as-syntax:

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

    我们可以将 .ts 与 as-syntax 一起使用,但 &lt;string&gt;someValue 很酷!

    【讨论】:

      猜你喜欢
      • 2023-03-22
      • 1970-01-01
      • 2012-07-16
      • 1970-01-01
      • 2023-04-06
      • 2020-05-18
      • 1970-01-01
      • 2015-05-25
      • 1970-01-01
      相关资源
      最近更新 更多