Bug报告
条件类型的文档缺少关于限制的重要信息。如果有人希望使用它们,会感到沮丧,因为它们不能按照人们的预期工作。文档中使用throw "unimplemented";并且没有关于实际实现时可能出现的问题的警告。
经过几个小时的尝试和搜索,我已经强烈地认为这是一个bug,我发现这是一个设计限制 - #22735
🔎 搜索词
条件类型不起作用,TS2322,条件类型,损坏的条件类型
问题代码
- 直接从文档中取用,并添加了简单的实现+解决方法。
- 在codesandbox上也是一样的:https://codesandbox.io/s/si8kv
interface IdLabel {
id: number /* some fields */;
}
interface NameLabel {
name: string /* other fields */;
}
type NameOrId<T extends number | string> = T extends number
? IdLabel
: NameLabel;
function createLabelBad<T extends number | string>(idOrName: T): NameOrId<T> {
if (typeof idOrName === 'string') {
return {name: idOrName}; // TS2322
}
return {id: idOrName}; // TS2322
}
function createLabelGood<T extends number | string>(idOrName: T): NameOrId<T> {
if (typeof idOrName === 'string') {
const nameLabel: NameLabel = {name: idOrName};
return nameLabel as any;
}
const idLabel: IdLabel = {id: idOrName};
return idLabel as any;
}
🙁 实际行为
文档中省略了非常重要的信息。这导致了不必要的沮丧、头痛和浪费时间。
🙂 预期行为
在文档中提到关于条件类型的限制的重要信息,可能还会提供一些解决方法,而不是throw "unimplemented";
5条答案
按热度按时间nle07wnf1#
See also #33912
rkue9o1l2#
See also #33912
Thank you! The workaround from that issue is the thing I would love to see in the documentation! With that information I am now able to make it much cleaner and safer.
eagi6jfj3#
感谢@psznm向我们分享了这个解决方法(这里是TypeScript playground的链接)。当前的文档没有充分解决这个问题,我花了两个小时才解决它...非常感谢!
0tdrvxhp4#
我刚来这里写同样的东西,发现了这个问题!
既然这是一个已知的限制/错误,文档至少应该提到推荐的解决方法,并实际为
createLabel
方法提供实现,而不是简单地抛出错误。仅供参考,除了 @psznm 的回答中你输入函数的返回值,你还可以使用条件类型化函数作为重载,并编写没有返回类型的函数(推断)。这也会起作用。
具体来说:
TSPlayground链接
cgyqldqp5#
我也遇到了这个问题。与其他人一样,当前的文档非常误导,因为它省略了实现部分。作为读者,我错误地认为实现是如此常见,以至于不需要详细说明,并且可以在函数内部正确推断出类型。
这个bug非常严重,让我觉得我快要疯了。甚至以下示例也失败了:
这个示例还被用在了 a short (and otherwise excellent) talk by Anders 中,那里的实现也被省略了!😄