microsoft / microsoft/TypeScript

Discriminant-specific error message not shown when one constituent of a union has a union-typed discriminant

未关闭
#37,488 3 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Experience Enhancement Suggestion
主要语言
Go
星标
111k
派生
14.3k
平均合并
2 天 4 小时
30 天内合并 PR
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.

Playground Link:
https://www.typescriptlang.org/v2/en/play?ts=next#code/JYOwLgpgTgZghgYwgAgILIN7IB4C5kgCuAtgEbTIC+AUKJLIigEKY74DOYUoA5ldbXDR4SZAFUAJOiwBrUABN8AclRKANMlIB7eQE986GnWGNxElrIXKm6zTv3IWRoQ1GSiAGw+s5IRciUAYSVkAB8AgBFbbT0AfnxCPwgYUAh5fmowXQAHFDFkAF4zdHDJFlKJTw8AbgF5CAQPOCgUGESEMGAtEGQYLS0ACkJ8MQBKfAA3LWB5Wuo+wYxffxVo+3wsPGQAFgAmKkpR2oWBpasAmw0Yh038PYOj6iA

Related Issues:
None that (at an uneducated guess) seemed to be exactly this one.

贡献指南

打开贡献指南

从这里开始

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

调研方向

从提供的 TypeScript Playground 复现开始,将第二次 foo 调用产生的诊断与预期的特定判别属性错误进行比较。跟踪处理带有联合类型判别属性的联合类型的 type-checker 路径;完成的标准是错误指向 x: 42,并报告 number 不可赋给 string,同时不回归已指出的变体。

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

评估

技术栈
typescript
领域
compilers
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
32/100

把新 issue 发到你的邮箱

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