microsoft / microsoft/TypeScript

Proposal: Easier Migration with Loose Mode in TypeScript Files

オープン
#22,665 コメント 2 件 リアクション 9 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Awaiting More Feedback Suggestion
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
1日 19時間
マージ済み PR(30日)
117

説明

This issue is the dual of #23906.

Background

TypeScript has always aimed at making migration from JavaScript as easy as possible; however, even today there exists a bit of an awkward gap where you must rewrite your JavaScript code to put it in a state where it's "ready" to be converted to TypeScript. As an example, users might start annotating their code with JSDoc to get better analysis in .js files, but once they switch their file extensions to .ts, TypeScript pretends like it doesn't understand those annotations anymore.

Proposal

TypeScript can provide a new "loose" mode (which we'll refer to as looseTs). This loose mode can be seen as a hybrid between the allowJs/Salsa language service support for JavaScript, along with TypeScript itself.

Let's explore what would this experience would look like.

Special JavaScript Declarations Are Allowed

TypeScript would understand certain constructs that are currently special cased in JS files. For example, the following construct would create what TypeScript effectively sees as a constructor.

function Foo() {
    this.x = 10;
    this.y = 20;
    this.z = 30;
}

new Foo().x + new Foo().y + new Foo().z // all well-typed as 'number'

Our language service could provide tooling to help refactor this to a more canonical sort of class.

Type Annotations & Declarations

All TypeScript constructs would continue to work, but so would JSDoc annotations & declarations.

/**
 * @typedef {PersonName} string
 */

export interface Person {
    // valid to reference JSDoc declarations in the same file
    name: PersonName;
}

TypeScript constructs would always take precedent over their JSDoc counterparts when they potentially conflict. For example, the following provides an error at worst, but will always consider x to be a string:

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

Class Properties

Today, TypeScript requires all classes to have property declarations.

Future versions of ECMAScript might allow property declarations.

The story here is: pick one. If classes contain no property declarations, then we'll fall back to Salsa-style inference from the constructor body. If any property declarations are present, then any access to this with a member that hasn't been declared is an error.

// Good!
class AllDeclared {
    a: number;
    constructor() {
        this.a = 0;
    }
}

// Good!
// Also, users get a quick fix.
class OnlyInitialized {
    constructor() {
        this.a = 0;
    }
}

// Bad!
class MixedDeclarationsAndInitialization {
    a: number;
    constructor() {
        this.a = 10;
        this.b = "hallo";
    }
}

We can provide tooling to help migrate users to TypeScript code that declares all of the initialized properties.

Best-Effort Completions

Like in Salsa, we should provide loose completions for things like any by default. This might be editor-configurable, but see #5334 for some more discussion.

More?

Your ideas here!

Drawbacks

One argument is that this could potentially dilute the value of the language, similar to concerns around // @ts-ignore.

Another related argument has to do with cognitive overhead. Our heuristics around understanding JavaScript constructs in Salsa (our JS language service) feels somewhat opaque. While we can document what special constructs we support, TypeScript's current model is significantly simpler. It might not be clear what features "proper TypeScript" actually supports (i.e. what exactly are you giving up when you turn off looseTs?)

Alternatives

We may want to consider alternatives before we commit to something like this.

Type Annotations in JavaScript Files

This proposal has proposed the idea of understanding Salsa/JS constructs in .ts files, but one could approach it from the other direction: Salsa could support type annotations in .js files instead under a specific mode. Our main concern here has been the conflation between what is possible in JavaScript today, and what constructs are specific to TypeScript. Additionally, providing non-standard constructs in .js files might give users the wrong impression over what we're trying to achieve (to clarify, in this issue, we're here to provide tooling for JavaScript users and make it easier to migrate to TypeScript).

Tooling Tooling Tooling Tooling

Now that we have suggestion diagnostics, we can potentially provide suggestions & tooling to just fix "legacy" JS constructs in the language service once you've moved to TypeScript. The counter-point here is that users will still likely experience the "sea of red" problem when you first switch a file over to .ts.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

実装ファイル、テスト、エントリーポイントは指定されていません。まず dual issue #23906 と関連する議論 #5334 を読み、そのうえで提案されている looseTs の動作について合意されたスコープがあるかどうかを判断してください。この issue では、具体的な受け入れ基準も、何をもって完了とするかも定義されていません。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
javascript, typescript
領域
compilers
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
説明が足りない
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。