TypeScript Misleading error message

n3ipq98p  于 6个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(43)

🔎 搜索词

误导性的错误信息

🕗 版本与回归信息

我认为在所有版本中,但我只尝试了5.2.2和5.3.0-beta

⏯ Playground链接

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgPIAczAPYgDwAqAfMgN4CwAUMjcsJALYD8AXMgQNxW3IzAQAbACYBnVsgAUAawgBPbDHYBKDgHpVyAK4jQAc2QADEWCh6A2gF0DyOCORhZ6FAAtoKAO7ZNw5AzgzkdGwRHQAjARQwV3swMBsQ4F0QBghwKgBfKgQBWzsCCGMAIVsIQmQIAA9IEFFkbFCAKwgEOIBeOsbmsBIKalpIYwkwNgwsXEIiJTJMyhnQSFhEFAARODA4Mm5aITW4NmNTEF0uWayckPYCsABhZ2AfSura-KKSvFX1nq2aAbAhkcwOHwHzgk2mGSoVAicViw0urxEKHaIAg7nhNzuwgkKiAA

💻 代码

interface Option<T> {
    item?: T;
    fields?: (keyof T);// using `string[]` as type here would make possible the ttt assignment
}
class TestBase<T extends object = object> {
    test(t: Option<T>) {}
}
interface Data {
    data: string;
}
class TestChild extends TestBase<Data> {
    test(t: Option<Data>) {}
}

let ttt: TestBase = new TestChild();

🙁 实际行为

在错误信息中,如果我将 ttt 悬停在上面,它会显示 item 成员不兼容,但我认为这不是问题所在,而是 fields 成员。如果我将其类型从 (keyof T)[] 更改为 string[],错误就会解决,但正如我所看到的,这意味着错误信息具有误导性。

🙂 预期行为

错误信息应该指出 fields 成员是有问题的。

关于问题的附加信息

我认为问题在于 fields 成员在基类(TestBase)中有类型 keyof object,这可能导致类型 never,在派生类(TestChild)中,fields 导致 "data",这显然不能分配给 never 类型。尽管我在 TypeScript 方面有多年的经验,但有时它仍然会让我感到惊讶。:)
另外:如果这是一个已知的问题或预期行为,请告诉我相应的文档。

uajslkp6

uajslkp61#

通过使用 keyof T,你使得 T 变为协变的(可以通过移除 item 属性并向 T 添加 in 注解来测试)。但是与此同时,T 是基于 item 属性的协变的 - 因此,总的来说,T 变成了不变的。TypeScript 不知道你实际上想要哪一个 - 所以它基于可变性测量的第一个不兼容的属性报错。

r1wp621o

r1wp621o2#

对我来说,不清楚是否有一个好的方法来改进这个问题,但有人可以尝试。Option<T> 写成这样是不变于 T 的,所以我们正在进行双向可分配性检查,一旦失败就立即失败。看到基于协变性的错误在协变属性上确实令人困惑,但可以说这个问题的“正确”修复方法就是简单地停止详细阐述 - 可能不是改进。寻找类型中的协变用法也可以说是更糟糕的,因为当我们可以直接谈论 ST 时,谈论 keyof Skeyof T 不匹配会更加令人困惑。

相关问题