Bug报告
在4.3.2或更高版本的typescript中,'Mapped Types'的转换结果发生了变化。
💻 代码
type Base = { 100: { a: number }; 200: { b: string } }
type NewType<T = Base> = {
[P in keyof T ]: {
code: P
body: T[P]
}
} extends {
[P in any]: infer R
}
? R
: never
let test: NewType
🙁 实际行为
- 4.3.0-beta及更早版本
let test: {
code: 100;
body: {
a: number;
};
} | {
code: 200;
body: {
b: string;
};
}
- 4.3.2
let test: {
code: keyof Base;
body: {
a: number;
} | {
b: string;
};
}
🙂 预期行为
希望恢复到4.3.0-beta之前的操作!
6条答案
按热度按时间jfewjypa1#
相关: #44143
5n0oy7gb2#
我能够通过插入一次'extends'来暂时解决这个问题!
这段代码在4.3.2及之前的版本中也有效。
qvtsj1bj3#
另一个解决方法(在ts 4.4.0-dev.20210530上尝试过):
de90aj5v4#
看起来这是被 #43649 破坏的。
yebdmbv45#
@weswigham 我不确定 #43649 的变化。他们在这个问题中破坏了示例,因为当我们检查
R
的推断是否可以分配给R
的约束(由 #43649 计算)时,该约束包含对T
的未示例化的引用,因此分配性检查失败。然后选择约束,随后使用传递给T
的类型示例化它。但那时已经太晚了,不是我们想要的结果。我们可能可以考虑在分配性检查之前添加一些逻辑来示例化约束,但这将进一步复杂化条件类型的推理过程,我甚至不确定我是否同意这是正确的做法。我认为对于推断出的R
没有约束是完全可以的——老实说,在许多类似的情况中,我们确实不会产生约束(例如,如果检查类型只是一个普通的对象类型)。我的建议是撤销 #43649。当然,这意味着 #43357,它修复的问题需要其他解决方案。正如你自己指出的那样,它从来就不应该起作用,我认为正确的解决方案是在
KeysWithoutStringIndex<T>
类型中显式与keyof T
相交,即k10s72fa6#
我认为我们的句法推断约束规则一开始是非常任意的(我们匹配哪些类型参数以及在哪些位置,这基本上是根据请求选择的)-我通过添加一个来"修复"这个问题,因为技术上说这种行为的变化实际上是一个回归,而添加这些句法约束是相对自由的。额外的示例化可能是我们能做的最好的事情,以保持旧的行为。我们可以撤销它...但是然后我们会重新引入旧的回归...