Typescript Iterable<;Iterable<;T>&燃气轮机;无法确认函数中的泛型T

Typescript Iterable<;Iterable<;T>&燃气轮机;无法确认函数中的泛型T,typescript,generics,type-inference,Typescript,Generics,Type Inference,这是我的问题 const iterable = [[[1,2,3]]] function flat<T>(t:Iterable<Iterable<T>>):Iterable<T>{ return [...t][0] } const flatted = flat(iterable) //return Iterable<unknown> 常量=[[1,2,3]] 函数平面(t:Iterable):Iterable{ 返回[…t

这是我的问题

const iterable = [[[1,2,3]]]
function flat<T>(t:Iterable<Iterable<T>>):Iterable<T>{
    return [...t][0]
}
const flatted = flat(iterable) //return Iterable<unknown>  
常量=[[1,2,3]]
函数平面(t:Iterable):Iterable{
返回[…t][0]
}
const flatted=flat(iterable)//返回iterable
上述函数不能假设T为数字,只需将其断言为未知。 此时此刻,我想,嗯。。。无法推断泛型中的泛型?'。但是下面的代码chuck工作得很好

const iterable = [[[1,2,3]]]
function flat<T>(t:Array<Array<T>>):Array<T>{
    return [...t][0]
}
const flatted = flat(iterable) // omg.. return Array<number> 
常量=[[1,2,3]]
函数平面(t:数组):数组{
返回[…t][0]
}
常数flatted=flat(iterable)//omg。。返回数组

常量=[[1,2,3]]
函数平面(t:Iterable):数组{
返回[…t][0]
}
const flatted=flat(iterable)//也可以使用。。返回数组
它们之间有什么区别?
谢谢你阅读我的问题。

哎呀,是的,我看到默认推理没有足够深入地将
Iterable
展开为
t
。如果您看看
Iterable
的打字方式,就不会感到惊讶了:

interface-Iterable{
[Symbol.iterator]():迭代器;
}
Iterable
有一个符号键控方法,其返回类型为
Iterator
,其本身如下所示:

接口迭代器{
下一个(…参数:[]|[TNext]):IteratorResult;
return?(value?:TReturn):IteratorResult;
抛出?(e?:任意):迭代或结果;
}
其中所有方法都返回
IteratorResult
,这将是一个有区别的联合类型

type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
type IteratorResult=IteratorYieldResult | IteratorReturnResult;
你是谁

接口迭代器IELDRESULT{
完成?:错误;
价值:泰菲尔德;
}
接口迭代器ReturnResult{
完成:正确;
值:TReturn;
}
其中只有一个具有您试图查找的相关类型
T
属性

因此,要将
Iterable
的类型
X
转换为
T
,编译器需要执行类似于
Extract['value']
(其中
I
是一个虚构的可索引
[Symbol.iterator]
属性,由于TypeScript中的错误,我们无法编写它)

我认为可能存在一些深度限制,在这个限制之后,编译器将放弃推断。您可以看到,从
Iterable
推断
T
是有效的(可能是5层或6层嵌套),但是从
Iterable
推断
T
太深了(10层或12层?):


type N=number[]?T:从来没有数字[]糟糕,是的,我看到默认推断没有足够深入地展开
Iterable
t
。如果您看看
Iterable
的打字方式,就不会感到惊讶了:

interface-Iterable{
[Symbol.iterator]():迭代器;
}
Iterable
有一个符号键控方法,其返回类型为
Iterator
,其本身如下所示:

接口迭代器{
下一个(…参数:[]|[TNext]):IteratorResult;
return?(value?:TReturn):IteratorResult;
抛出?(e?:任意):迭代或结果;
}
其中所有方法都返回
IteratorResult
,这将是一个有区别的联合类型

type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
type IteratorResult=IteratorYieldResult | IteratorReturnResult;
你是谁

接口迭代器IELDRESULT{
完成?:错误;
价值:泰菲尔德;
}
接口迭代器ReturnResult{
完成:正确;
值:TReturn;
}
其中只有一个具有您试图查找的相关类型
T
属性

因此,要将
Iterable
的类型
X
转换为
T
,编译器需要执行类似于
Extract['value']
(其中
I
是一个虚构的可索引
[Symbol.iterator]
属性,由于TypeScript中的错误,我们无法编写它)

我认为可能存在一些深度限制,在这个限制之后,编译器将放弃推断。您可以看到,从
Iterable
推断
T
是有效的(可能是5层或6层嵌套),但是从
Iterable
推断
T
太深了(10层或12层?):


type N=number[]?T:从来没有数字[]可能是TypeScript推断对展开嵌套数组有更好的支持?请注意,
Array
与TypeScript中的
T[][]
相同,
flatted
实际上是
number[][]
,而不是
number[]
对不起,没有我的解释,我将添加更多内容。嵌套数组似乎只能推断
Iterable
也可以推断
number[][][]
,因为numberI不能用参数进行陈述,所以接受它作为一个自以为是的语句,但IMHO TypeScript在泛型和从泛型推断类型方面存在一些问题。我有过和你一样的经历,在那里它显然可以推断出类型,但它不能。看起来是一个糟糕的实现或bug,IDK。@EugeneObrezkov,谢谢你的回复。如果这可能是真的,天哪。。我希望在某个地方能找到解决方案。在这种情况下,我只是在需要的地方显式地传递type参数,TypeScript推断只是更好地支持展开嵌套数组?请注意,
Array
与TypeScript中的
T[][]
相同,
flatted
实际上是
number[][]
,而不是
number[]
对不起,没有我的解释,我将添加更多内容。嵌套数组似乎只能推断
Iterable
也可以推断
number[][][]
,因为numberI不能用参数进行陈述,所以接受它作为一个自以为是的语句,但IMHO TypeScript在泛型和从泛型推断类型方面存在一些问题。我有过和你一样的经历,在那里它显然可以推断出类型,但它不能。看起来是一个糟糕的实现或bug,IDK。@EugeneObrezkov,谢谢你的回复。如果
interface Iterator<T, TReturn = any, TNext = undefined> {
    next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
    return?(value?: TReturn): IteratorResult<T, TReturn>;
    throw?(e?: any): IteratorResult<T, TReturn>;
}
type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
interface IteratorYieldResult<TYield> {
    done?: false;
    value: TYield;
}

interface IteratorReturnResult<TReturn> {
    done: true;
    value: TReturn;
}