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;
}