我刚开始用TypeScript做一个React项目,问自己该怎么处理常规类文件?我应该使用。ts或。tsx文件,然后我找不到任何理由不使用。tsx文件的所有时间,即使它不是一个React项目!
是否有任何原因或特定情况,我们不应该使用.tsx文件?如果没有,为什么TypeScript团队添加了一个全新的扩展?
我刚开始用TypeScript做一个React项目,问自己该怎么处理常规类文件?我应该使用。ts或。tsx文件,然后我找不到任何理由不使用。tsx文件的所有时间,即使它不是一个React项目!
是否有任何原因或特定情况,我们不应该使用.tsx文件?如果没有,为什么TypeScript团队添加了一个全新的扩展?
当JavaScript处于JSX Harmony模式时,使用x是一种惯例。也就是说,当这是有效的:
doSomething(<div>My div</div>);
然而,你的文件扩展名并不重要,只要你的预处理器知道你的决定(browserify或webpack)。就我而言,我所有的JavaScript都使用.js,即使它们是React。同样适用于TypeScript, ts/tsx。
EDIT
现在,我强烈建议Javascript使用JSX, TypeScript使用TSX,因为大多数编辑器/ ide都会使用扩展来启用或不启用React语法。它也被认为是更有表现力。
你可以用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而不是<>。这实际上是在TypeScript中引入的,因为<>在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;}
Note
虽然你可以用tsx代替ts,但我建议不要这样做。约定是一个强大的东西,人们将tsx与jsx联系起来,可能会惊讶于你没有任何jsx标记,最好将开发人员的惊喜保持在最低限度。
虽然上面的歧义并不大(虽然可能不是一个完整的列表),但它们可能在决定为新语法使用专用的文件扩展名以保持ts文件向后兼容方面发挥了重要作用。
引入. JSX扩展名的原因是JSX是JS语法的扩展,因此. JSX文件不包含有效的JavaScript。
TypeScript通过引入.ts和.tsx扩展名遵循相同的约定。一个实际的区别是.tsx不允许<Type>类型断言,因为语法与JSX标记冲突。as类型断言被引入作为<Type>的替代,并且由于.ts和.tsx中的一致性原因被认为是首选。如果.ts中的代码在.tsx文件中使用,<Type>将需要修复。
使用.tsx扩展名意味着模块与React相关,并使用JSX语法。如果它没有,扩展可能会给人一个关于模块内容和项目中的角色的错误印象,这是反对默认使用.tsx扩展的论点。
另一方面,如果一个文件与React相关,并且很有可能在某个时刻包含JSX,那么可以从一开始就将其命名为.tsx,以避免以后重命名。
例如,与React组件一起使用的实用函数可能在任何时候都涉及到JSX,因此可以安全地使用。tsx名称,而Redux代码结构不应该直接使用React组件,可以在React之外使用和测试,并且可以使用。ts名称。
.ts文件有一个<AngleBracket>类型的断言语法,这与JSX语法冲突。为了避免破坏大量的人,我们使用。tsx作为JSX,并添加了foo作为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语法,但是<string>someValue很酷!