这个问题是 #22665 的双胞胎。
背景
在上周的设计会议上,我们讨论了 #22665 ,看起来我们在提议中有一些积极的情绪。具体来说,当用户在迁移到 .ts
文件时遇到表达能力墙或 .js
中的不匹配问题时,这些问题提供了一个令人信服的案例。
然而,这个提议也有一些问题:
- 它仍然需要用户将文件扩展名从
.js
更改为.ts
,这通常意味着需要改变构建步骤。 - 它没有提供从使用
.js
文件中的注解语法的其他类型系统中轻松迁移的路径(参见 Using typescript babel to transition from flow TypeScript-Babel-Starter#1 )。 - 它引入了“稀释/松散”的 TypeScript 体验的概念,这可能会使事情变得更加混乱。
建议
我们可以引入一种新模式,使 TypeScript 特定的构造函数能够在 .js
文件中使用。这种新模式将允许像类型注解、 interface
、类属性注解等在 .js
文件中声明。用户必须明确选择加入此模式,以便过渡到 TypeScript。
支持的构造函数
以下来自 TypeScript 的支持构造函数:
- 类型注解 (
: Foo
) - 接口 (
interface Foo { /*...*/ }
) - 类型别名 (
type Foo = "hello" | "world"
) as
风格的类型Assert (xyz as SomeType
)- 非空类型Assert (
x!.bar
) - 确定性赋值Assert (
let x!: number
) - 枚举 (
enum E { /*...*/ }
) - 导入别名和导出别名:
- `import
不支持的构造函数
为了鼓励用户编写利用后期绑定的 ECMAScript 模块和标准枚举,以下构造函数将不受支持。
- 命名空间
const
枚举
已存在的带类型的 .js
文件语义
JavaScript 文件仍然具有相同的专门语义,包括理解诸如 CommonJS 模块、JSDoc 类型注解、ES5-style 构造函数函数、对象字面量可能具有开放性等事物。然而,在存在类似 TypeScript 构造函数的情况下,TypeScript 构造函数总是获胜。例如,以下声明将 x
作为类型 number
,并可能在 JSDoc 上发出错误。
/**
* @type {string}
*/
var x: number;
缺点
这个提议避免了与 #22665 相关的上述问题,但也有一些新的缺点。
一方面,从一个 .js
文件迁移到一个 .ts
文件似乎没有什么优势,即使 TypeScript 更易于推理和做出假设(而我们的 JavaScript 语义更多是“尽力而为”)。
另一个问题可能更大,那就是这混淆了 JavaScript 的终点和 TypeScript 的起点。虽然这里的意图是使迁移更容易,但启用此功能可能会被误认为是试图不适当地扩展语言的企图。虽然我们希望用户理解这不是这样,但我们非常愿意就这个问题听取社区的反馈。如果这个标志被命名为类似于 --jsMigrationMode
这样的东西,也许我们可以更明确地表达意图,并向用户传达拥有此标志并不理想。
先例
Babel 生态系统中 JSX 和 Flow 在 .js
文件中的常见用法(而不是使用 .jsx
文件扩展名)为支持在 .js
文件中使用 TypeScript 构造函数提供了合理的先例。
4条答案
按热度按时间ev7lccsx1#
以下内容将不被支持,以鼓励用户编写使用延迟绑定的ECMAScript模块和标准枚举。
我们为什么要做出这种区分呢?您在现有先例部分中列出了已添加到.js文件中的非ES-标准语法的工具。我想说的是,只需在.js文件中启用所有TS语法即可。
qfe3c7zg2#
我认为现在可以使用Babel 7来去除TypeScript类型。
6l7fqoea3#
使用JSDoc,类型信息通过标准的JavaScript注解与JavaScript隔离。这意味着您可以直接在浏览器、NodeJS或其他仅假设标准JavaScript的上下文中使用JavaScript文件。
通过这个提案,TypeScript类型定义将直接嵌入到JavaScript中,就像它是TypeScript一样。这意味着它必须有一个构建步骤来移除这些信息。恐怕用户可能没有意识到这种区别,并认为,就像JSDoc类型信息一样,具有这种TypeScript类型的文件可以用于任何可能的JavaScript上下文(浏览器、NodeJS等)。
pgpifvop4#
对于尚未使用TS的项目,此功能几乎没有价值。无论如何,您都需要重构您的构建过程(因为旧的基于JS的工具在TS语法上会崩溃)。与此相比,将
.js
重命名为.ts
实际上并不费力。这可能只对那些出于某种原因已经通过TSC运行了
.js
并希望使用更多TS好处的人有帮助,但还没有准备好将文件重命名为.ts
的人有用。听起来对于太狭窄的受众来说收益太小了。另一方面,它可能会造成巨大的混乱。人们会因为没有意识到他们正在删除源文件而不是构建产品而失去他们的工作。
想想这个结果文件会放在哪里?