microsoft / microsoft/TypeScript

Proposal: Easier Migration with Types in JavaScript Files

未关闭
#23,906 4 条评论 4 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Awaiting More Feedback Suggestion
主要语言
Go
星标
111k
派生
14.4k
平均合并
1 天 19 小时
30 天内合并 PR
117

描述

This issue is the dual of #22665.

Background

In last week's design meeting, we discussed #22665 and it seemed like we had some positive sentiment around the proposal. Specifically, issues where users hit an expressivity wall or mismatch in .js when migrating to .ts files provide a compelling case.

However, there are certain issues with the proposal:

  • It still requires users to make a file extension change from .js to .ts, which usually implies some change in build steps.
  • It provides no easy migration path from other type systems with annotation syntax used in .js files (see https://github.com/Microsoft/TypeScript-Babel-Starter/issues/1).
  • It introduces the concept of a "diluted/loose" TypeScript experience which can make things more confusing.

Proposal

We can introduce a new mode that enables TypeScript-specific constructs in .js files. This new mode would allow things like type annotations, interfaces, class property annotations, etc. to be declared in .js files. Users would have to explicitly opt-in to this mode for transitionary purposes, with the end goal of migrating to TypeScript.

Supported constructs

The following constructs from TypeScript would be supported:

  • Type annotations (: Foo)
  • Interfaces (interface Foo { /*...*/ })
  • Type alias (type Foo = "hello" | "world")
  • as-style type assertions (xyz as SomeType)
  • Non-nullable type assertions (x!.bar)
  • Definite assignment assertions (let x!: number)
  • Enums (enum E { /*...*/ })
  • Import aliases and export aliases:
    • `import

Unsupported constructs

The following would not be supported to encourage users to write ECMAScript modules and standard enums that utilize late-binding.

  • Namespaces
  • const enums

Existing typed .js file semantics

A JavaScript file still has the same specialized semantics including understanding things like CommonJS modules, JSDoc type annotations, ES5-style constructor functions, object literals potentially being open-ended, etc. However, in the presence of an analogous TypeScript construct, the TypeScript construct always wins. For example, the following declares x as type number, and potentially issues an error on the JSDoc.

/**
 * @type {string}
 */
var x: number;

Drawbacks

This proposal avoids the aforementioned issues with #22665, but has some new drawbacks.

For one, it seems like there's little-to-no advantage to moving from a .js file to a .ts file, even though TypeScript is easier to reason about and make assumptions on (whereas much of our JavaScript semantics are more "best-effort").

The other issue, which is likely much bigger, is that this conflates where JavaScript ends and TypeScript begins. While the intent here is to make migration easier, enabling this functionality could be perceived poorly as an attempt to extend the language inappropriately. While we hope users understand this is not the case, we are extremely open to feedback from the community on this issue.

If this flag was called something like --jsMigrationMode, perhaps we could be explicit on the intent and also signal to users that having this flag on is not ideal.

Existing Precedent

Common usage of JSX and Flow in .js files in the Babel ecosystem (as opposed to using the .jsx file extensions) provides a reasonable precedent for supporting TypeScript constructs in .js files.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

先阅读该提案支持和不支持的构造,然后查看相关 issue #22665 以及链接的 Babel Starter 讨论。没有列出任何实现文件、测试或编译器入口点,因此首要任务是在定义完成意味着什么之前,确定设计和受影响的范围。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, typescript
领域
compilers
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
基本清楚
新手友好度
30/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。