typescript - 如何展开异步或同步生成器
我想解包一个异步生成器或同步生成器,并获取它的内部返回类型。
也就是说,我在寻找一个用于 Promise 的 Awaited 的等效物。
对于我曾经做出的承诺:
async function foo() {
}
let returnValue: Awaited<ReturnType<typeof foo>>;
对于发电机,我正在寻找:
async function* foo() {
}
function* bar() {
}
let returnValue: ???<ReturnType<typeof foo | typeof bar>>;
答案#1
es2015.iterable 包含你可以用来推断 yield 值的 Generator 类型:
function* foo() {
yield 1;
yield 2;
}
function* bar() {
yield 3;
yield 4;
}
type GeneratorValue<G extends (...arg: any[]) => any> = ReturnType<G> extends Generator<infer X> ? X : never;
type fooG = GeneratorValue<typeof foo | typeof bar> // 1 | 2 | 3 | 4
操场
使用这个为异步生成器打字不起作用,我也不能轻松地从现有接口扩展 AsyncGenerator 类型,但似乎某种程度上是可能的。
答案#2
你可以像实现 ReturnType 那样实现你的工具类型,只不过不是推断整个返回类型,而是推断 AsyncGenerator 和 Generator 泛型类型的类型参数(因为当你在 TypeScript 中查看生成器/异步生成器函数的声明时,它们返回的就是这些类型):
type GenYieldType<T extends (...args: any) => Generator<any, any, any>> =
T extends (...args: any) => Generator<infer R, any, any> ? R : never;
type AsyncGenYieldType<T extends (...args: any) => AsyncGenerator<any, any, any>> =
T extends (...args: any) => AsyncGenerator<infer R, any, any> ? R : never
让我们来试试:
async function* foo() { yield "a"; yield "b"; }
type FooYield = AsyncGenYieldType<typeof foo>
// ^? type FooYield = "a" | "b"
function* bar() { yield "c"; yield "d"; }
type BarYield = GenYieldType<typeof bar>
// ^? type BarYield = "c" | "d"
看起来不错。
代码的 Playground 链接
