microsoft / microsoft/TypeScript
Refinement type inference quirk with implicitly typed `let x`
まだ誰も着手していません。
- 主要言語
- Go
- スター
- 111k
- フォーク
- 14.4k
- 平均マージ
- 1日 19時間
- マージ済み PR(30日)
- 117
説明
🔎 Search Terms
refinement narrow let any
🕗 Version & Regression Information
- This changed between versions 3.9.7 and 4.0.5; the behavior is present in every version from 4.0.5 to 5.3 nightly; I skimmed the whole FAQ document and didn't find anything relevant
⏯ Playground Link
💻 Code
type MyType = { type: 'A' } | { type: 'B' };
function f(arg: MyType) {
let x;
x = arg;
if (x.type === 'A') {
} else if (x.type === 'B') {
} else {
let _: never = x;
}
}
🙁 Actual behavior
error TS2322: Type '{ type: "B"; }' is not assignable to type 'never'.
9 let _: never = x;
~
This is wrong for two reasons:
- In the world of perfect type inference,
xshould be narrowed toneverat this point - Even acknowledging that there could be some practical limitations, the behavior is not consistent.
First conditional successfully eliminates the "A" variant:
But second conditional fails to eliminate the "B" variant:
🙂 Expected behavior
Ideally, this shouldn't be an error at all.
However, given that control-flow-based type inference has its limitations, perhaps some kind of spurious error is inevitable. In that case, it probably should be more like Type 'MyType' is not assignable to type 'never' rather than Type '{ type: "B" }' is not assignable to type 'never'.
Additional information about the issue
Practical impact of this issue is small. There is an easy workaround of adding an explicit type annotation (let x: MyType;).
However, this asymmetry, that the last conditional fails at narrowing when exactly the same conditional before that succeeds, bothers me. I'm reporting this because it could be a symptom of a more general implementation defect.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず TypeScript Playground の例を再現し、報告されたバージョン間で動作を比較します。MyType から代入された暗黙的に型付けされた let について、制御フローに基づく型推論と型の絞り込みを調査します。完了条件は、最後の else 分岐が一貫して絞り込まれるか、以前の絞り込みを壊すことなく合意した診断が生成されることです。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- typescript
- 領域
- compilers
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- 明確に書かれている
- 初心者へのやさしさ
- 35/100