🔎 搜索词
误导性的错误信息
🕗 版本与回归信息
我认为在所有版本中,但我只尝试了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 方面有多年的经验,但有时它仍然会让我感到惊讶。:)
另外:如果这是一个已知的问题或预期行为,请告诉我相应的文档。
2条答案
按热度按时间uajslkp61#
通过使用
keyof T
,你使得T
变为协变的(可以通过移除item
属性并向T
添加in
注解来测试)。但是与此同时,T
是基于item
属性的协变的 - 因此,总的来说,T
变成了不变的。TypeScript 不知道你实际上想要哪一个 - 所以它基于可变性测量的第一个不兼容的属性报错。r1wp621o2#
对我来说,不清楚是否有一个好的方法来改进这个问题,但有人可以尝试。
Option<T>
写成这样是不变于T
的,所以我们正在进行双向可分配性检查,一旦失败就立即失败。看到基于协变性的错误在协变属性上确实令人困惑,但可以说这个问题的“正确”修复方法就是简单地停止详细阐述 - 可能不是改进。寻找类型中的协变用法也可以说是更糟糕的,因为当我们可以直接谈论S
和T
时,谈论keyof S
与keyof T
不匹配会更加令人困惑。