- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是我的问题。
const iterable = [[[1,2,3]]]
function flat<T>(t:Iterable<Iterable<T>>):Iterable<T>{
return [...t][0]
}
const flatted = flat(iterable) //return Iterable<unknown>
上面的函数不能假设 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>
还有
const iterable = [[[1,2,3]]]
function flat<T>(t:Iterable<Array<T>>):Array<T>{
return [...t][0]
}
const flatted = flat(iterable) // also works.. return Array<number>
它们之间有什么区别?感谢您阅读我的问题。
最佳答案
糟糕,是的,我发现默认推理的工作深度不足以展开 Iterable<Iterable<T>>
进入T
.如果您查看 Iterable
的类型,这并不令人惊讶。是defined in the relevant library :
interface Iterable<T> {
[Symbol.iterator](): Iterator<T>;
}
安Iterable<T>
有一个符号键控方法,其返回类型为 Iterator<T>
,它本身就是 defined作为:
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>;
}
所有方法都返回 IteratorResult<T, ...>
,即 defined成为受歧视的工会类型
type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
谁的members是
interface IteratorYieldResult<TYield> {
done?: false;
value: TYield;
}
interface IteratorReturnResult<TReturn> {
done: true;
value: TReturn;
}
其中只有一个有 value
相关类型的属性(property)T
你正在寻找。
所以要转一个类型X
的 Iterable<T>
进入T
, 编译器需要做类似 Extract<ReturnType<ReturnType<X[typeof Symbol.iterator]>['next']>, { done?: false }>['value']
的事情.
我认为可能存在一些深度限制,在该限制之后编译器会放弃尝试推断事物。你可以看到推断 T
来自 Iterable<T>
有效(可能有 5 或 6 层嵌套),但推断 T
来自 Iterable<Iterable<T>>
太深了(10 层还是 12 层?):
type N = number[][] extends Iterable<infer T> ? T : never; // number[] 👍
type O = number[][] extends Iterable<Iterable<infer T>> ? T : never; // unknown 👎
这使我想到了以下解决方法:创建一个类型别名以在 Iterable
的一层上显式操作,然后使用它两次:
type DeIterable<T extends Iterable<any>> = T extends Iterable<infer U> ? U : never;
你可以看到这个有效:
type Okay = DeIterable<DeIterable<number[][]>>; // number 👍
现在flat()
可以这样定义:
function flat<II extends Iterable<Iterable<any>>>(
t: II
): Iterable<DeIterable<DeIterable<II>>> {
return [...t][0]
}
其中输入值是泛型类型II
, 我们使用 DeIterable
两次获得 T
你之前想要的:
const flatted = flat(iterable) //return Iterable<number[]>
现在看起来不错!好的,希望有所帮助;祝你好运!
关于typescript - Iterable<Iterable<T>> 无法确认函数中的泛型 T,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61506176/
我是一名优秀的程序员,十分优秀!