Typescript 无法推断 Iterable 的 Iterable 的内部类型

Typescript can't infer inner type of Iterable of Iterable

这是一个简单的函数,它接受一个 Iterable of Iterables。

function unwrapFirst<T extends Iterable<U>, U>(iter: Iterable<T>): U {
  return [...[...iter][0]][0];
}

unwrapFirst([[1,2,3],[4,5,6]]);

我希望 TypeScript 能够将 U 的类型正确推断为 number,但它却将其推断为 unknown。有人可以解释为什么吗?以及如何让 TypeScript 正确推断 U?

Generic constraints are not used as inference sites. See microsoft/TypeScript#44711 类似问题。

鉴于 T 被限制为 Iterable<U>,您可能希望编译器从 T 推断出 U。但这不会发生,因为约束没有被用作推理站点。所以为 T 推断出的类型对 U 没有影响,因此 U 推断失败,编译器 falls back to unknown.

如果你想使用推理从T得到U,你将只在T中使函数通用,然后通过[=计算U 25=]。例如:

function unwrapFirst<T extends Iterable<any>>(
    iter: Iterable<T>
): T extends Iterable<infer U> ? U : never {
    return [...[...iter][0]][0];
}

const res = unwrapFirst([[1, 2, 3], [4, 5, 6]]);
// const res: number

看起来不错!

Playground link to code