microsoft / microsoft/TypeScript
Discriminant-specific error message not shown when one constituent of a union has a union-typed discriminant
まだ誰も着手していません。
- 主要言語
- Go
- スター
- 111k
- フォーク
- 14.3k
- 平均マージ
- 2日 4時間
- マージ済み PR(30日)
- 132
説明
TypeScript Version: 3.9.0-dev.20200319
Search Terms: discrimant tagged union assignable
Code
A simplified repro, based on real-world code:
interface A { x: number }
interface B { x: string }
interface U$A { kind: 'A', body: A }
interface U$B { kind: 'B', body: B }
interface U$null { kind: 'C' | 'D', body?: undefined }
type U = U$A | U$B | U$null;
declare function foo(u: U): void;
foo({kind: 'A', body: { x: 42 }}); // OK
foo({kind: 'B', body: { x: 42 }}); // Not OK
Expected behavior:
The second x: 42 gets a squiggle and and the error Type 'number' is not assignable to type 'string'.
Actual behavior:
The whole argument to the second foo call gets a squiggle and the error:
Argument of type '{ kind: "B"; body: { x: number; }; }' is not assignable to parameter of type 'U'. Type '{ kind: "B"; body: { x: number; }; }' is not assignable to type 'U$null'. Types of property 'kind' are incompatible. Type '"B"' is not assignable to type '"C" | "D"'.
I would expect the type of the argument to have been narrowed to U$B by checking the kind property first. As it stands, the developer UX is not ideal especially when the shapes of the types involved get larger and it gets quite hard to figure out which property is wrong (in my real-world case, the union has 250+ members and the error message is incomprehensible).
Notes:
If I change x to y in interface B, the error message comes up OK.
Also, if I comment out the two references to U$null, I get a different (but also acceptable) error.
Related Issues:
None that (at an uneducated guess) seemed to be exactly this one.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
提供された TypeScript Playground の再現コードから始め、2 回目の foo 呼び出しに対して生成される診断を、期待される判別子固有のエラーと比較します。union 型の判別子を持つ union を処理する type-checker の経路を追跡します。x: 42 を指し、number を string に割り当てられないと報告するエラーになり、記載されたバリエーションにリグレッションが発生しなければ完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- typescript
- 領域
- compilers
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 32/100