Bug报告
🔎 搜索词
- Array.flat
- 类型示例化过于深入,可能是无限的。
- 嵌套数组
🕗 版本与回归信息
- 在版本4.6和4.7之间发生了变化
⏯ Playground链接
带有相关代码的TypeScript Workbench
💻 代码
interface Config {
prop?: string;
}
interface ExtendedConfig extends Config {}
type NestedConfigs = Array<ExtendedConfig | NestedConfigs>;
const configs: NestedConfigs[] = [];
const flattened = configs.flat(Infinity);
🙁 实际行为
对于 configs.flat(Infinity)
调用,TypeScript会引发以下错误:Type instantiation is excessively deep and possibly infinite. ts(2589)
🙂 预期行为
不应引发错误。
8条答案
按热度按时间ercv8c1e1#
今天在4.7.2版本中也遇到了这个问题。在4.6版本中,输出被错误地显示为
any[]
(playground)。ogq8wdun2#
在从4.6.4升级到4.7.2的过程中,也遇到了这个问题。整个应用程序无法编译。
qq24tv8q3#
刚刚也遇到了这个问题,这里有一个非常简洁的例子:
在
args.flat(Infinity)
上出现了完全相同的错误,"类型示例化过于深入,可能是无限的。"目前快速的解决方案是将你的
.flat
参数Assert为整数:args.flat(Infinity as 10)
这应该会使错误消失。
rkue9o1l4#
我不太确定如何对此进行推理。这个错误在所有情况下都是正确的。你可以写
这会导致
如果你有一个有限深度(T | T[])[],那么最好将一个有限参数传递给
flat
。如果你确信深度实际上是由某个不可知的高精度整数(????)限制的,那么对Infinity
进行类型Assert到一个较低的整数(我强烈建议使用1
,而不是10
,因为它们实际上执行不同级别的解包),这似乎是合适的Assert,因为你比 TypeScript 对这种情况下的数据结构了解更多。ttvkxqim5#
我不确定我认为正确的输出类型是什么,但在我看来,TypeScript编译器应该允许
.flat(Infinity)
(没有类型Assert)而不直接失败编译,因为它是有效的和常见的JavaScript(例如MDN上的示例)。也许将
Infinity
特殊处理以得到unknown[]
或any[]
是合理的?c9qzyr3d6#
我应该也指出,作为一个TypeScript的用户,"可能无限"的东西对我来说是有足够意义的,但我对如何绕过类型错误有点困惑,因为这种错误阻止了像
configs.flat(Infinity) as Config[]
这样的后置转换。gstyhher7#
Type-asserting
Infinity
to a lower integer (I'd really recommend1
, not10
, as they actually do different levels of unwrapping) if you're confident that the depth is actually bounded by some unknowably-high integer (????) seems like an appropriate assertion, since you know more than TypeScript does about the data structure in this case.Oh, that's really interesting, I actually didn't know that. So to get more specific, in my use case I was actually using it within a function that allows one to optionally declare a flattening depth. To go off of my example, that might look like:
The intent here was to mimic something like a
flat(Infinity)
, Hence the assertion to a higher integer. I'm assuming that because in this instancedepth
can beInfinity
, that it gives that error. If TS treats the type-assertion with different levels of unwrapping, it might be worth it to lower that depth instantiation just for those gains.I tend to agree with @grant-dennison above, it seems like
.flat(Infinity)
feels commonplace enough to warrant TypeScript handling this in a way that makes sense with (T | T[])[] types for flattening them. That being said, I do see how that gets very hairy, very fast.A potential middle-ground here may be some form of 'non-infinite' integer or number type. To go back to my example:
That way I can tell TypeScript that this is actually bounded by some unknowably-high integer, and have type errors if I try to call
fancyFlatten
withInfinity
nue99wik8#
如果为
Infinity
添加了字面类型,这个问题就可以得到解决:使用1e309
的 playground link。