我有以下生成器函数:
async function * filterIterable (iter, predicate) {
let i = 0
for await (const val of iter) {
if (predicate(val, i++)) {
yield val
}
}
}
我想针对以下两种情况输入:
// type predicate
const nonNullable = <T>(val: T | undefined | null): val is T =>
val !== undefined && val !== null
async function * gen1 () {
yield 1
yield 2
yield 3
}
async function * gen2 () {
yield 1
yield undefined
yield 3
}
const it1 = filterIterable(gen1(), n => n % 2 === 0)
const it2 = filterIterable(gen2(), nonNullable) // should be AsyncIterable<1 | 2>
我想出了这个界面:
interface FilterIterable {
<T> (
iter: AsyncIterable<T>,
predicate: (val: T, index: number) => boolean,
): AsyncIterable<T>;
<T, S extends T> (
iter: AsyncIterable<T>,
predicate: (val: T, index: number) => val is S,
): AsyncIterable<S>;
}
我可以将其应用于函数表达式,但显然不适用于如何将函数类型应用于函数声明的函数声明。这不就是生成器吗?
所以你想
filterIterable()
成为一个具有多个调用签名的重载函数。虽然您目前确实无法按照microsoft/TypeScript#22063中的要求直接注释函数,但您可以仅使用常规重载语法并在实现之前声明调用签名:现在应该可以按您的预期工作:
Playground 代码链接