microsoft / microsoft/TypeScript

Consider property access a form of type guards

オープン
#1,260 コメント 18 件 リアクション 89 件 担当者 0 名 GitHub で見る

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

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

説明

This is a proposal for using property access as another form of type guards (see #900) to narrow union types. While we're investigating expanding the power of type guards (#1007) this feature would support the natural style that JavaScript programmers have in their code today.

Using property access to narrow union types
var x: string|number;
if (x.length) { // no error even though number lacks a length property
    var r = x.charAt(3); // x is of type string inside this block
}

var r2 = x.length || x * x; // no error, x narrowed to number on right hand side, r3 is number

var y: string[]|number[]|string;
if (y.length && y.push) {
    // y is string[]|number[] now
    var first = y[0]; // first is string|number
    if (first.length) {
        // first is string in here
    } else {
        // first is number in here
    }
}

We do not expand the situations in which types are narrowed, but we do expand the known type guard patterns to include basic property access. In these narrowing contexts it would be an error to access a property that does not exist in at least one of the constituent types of a union type (as it is today). However, it would now be valid to access a property that exists in at least one, but not all, constituent types. Any such property access will then narrow the type of the operand to only those constituent types in the union which do contain the accessed property. In any other context property access is unchanged.

Invalid property access
var x: string|number;

var r = x.length; // error, not a type guard, normal property access rules apply

if (x.len) { } // error, len does not exist on type string|number 

var r3 = !x.len && x.length; // error, len does not exist on type string|number 

var r4 = x.length && x.len; // error, len does not exist on type string
Issues/Questions
  • Should the language service behave differently in these type guard contexts? Should dotting off a union type in a type guard list all members on all types rather than only those that exist on all of them?
  • Need to understand performance implications

I have a sample implementation and tests in a branch here: https://github.com/Microsoft/TypeScript/tree/typeGuardsViaPropertyAccess. There're a couple bugs remaining but examples like the above all work and no existing behavior was changed.

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

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

はじめの一歩

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

調査の方向性

Issue にリンクされている typeGuardsViaPropertyAccess ブランチから始め、そのサンプル実装とテストを確認してください。この issue の例と無効なアクセスのケースを、#900 および #1007 で議論されている既存の type guard の動作と比較してください。残っているバグを解決し、language service とパフォーマンスに関する疑問に対応し、提案された narrowing ルールのテストを追加または更新すれば完了です。

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

評価

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

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

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