我正在尝试在TypeScript中创建*-as-promised
version async
库,重用@types/async
类型。
我的问题是@types/async at the .filter function正在导出两个具有相同名称的函数类型:
export function filter<T, E>(arr: T[] | IterableIterator<T>, iterator: AsyncBooleanIterator<T, E>, callback?: AsyncResultArrayCallback<T, E>): void;
export function filter<T, E>(arr: Dictionary<T>, iterator: AsyncBooleanIterator<T, E>, callback?: AsyncResultArrayCallback<T, E>): void;
但我only export one .filter function:
function filter<T>(
arr: async.Dictionary<T> | T[] | IterableIterator<T>,
iterator: (item: T) => Promise<boolean>
): Promise<Array<(T | undefined)> | undefined> {
return new Promise((resolve, reject) => {
async.filter(arr, (item, cb) => {
iterator(item)
.then(res => cb(undefined, res))
.catch(err => cb(err));
}, (err, results) =>
err
? reject(err)
: resolve(results)
);
});
}
编译时,会出现以下错误:
lib/filter.ts(32,18): error TS2345: Argument of type 'Dictionary<T> | IterableIterator<T> | T[]' is not assignable to parameter of type 'Dictionary<T>'.
Type 'IterableIterator<T>' is not assignable to type 'Dictionary<T>'.
那么,我怎样才能将这些声明合并为一个?
谢谢你。
答案 0 :(得分:1)
奇怪的是,键入不是具有arr
参数的三种可能类型的并集的单个函数签名。您可能需要考虑向async
输入库提交问题或拉取请求以进行修复。
即便如此,如果编译器允许你以你的方式调用函数会很好,因为你知道这样做是安全的。但正如您所见,it won't,至少从TypeScript v2.5开始。
最简单的解决方法:因为您知道编译器不知道的事实...即,现有的filter
函数确实会接受类型为arr
的{{1}} ,通过声明T[] | IterableIterator<T> | Dictionary<T>
类型arr
禁用类型检查来告诉编译器不要担心:
any
还有其他解决方法,例如根据function filter<T>(
arr: async.Dictionary<T> | T[] | IterableIterator<T>,
iterator: (item: T) => Promise<boolean>
): Promise<Array<(T | undefined)> | undefined> {
return new Promise((resolve, reject) => {
async.filter(arr as any, (item, cb) => {
iterator(item)
.then(res => cb(undefined, res))
.catch(err => cb(err));
}, (err, results) =>
err
? reject(err)
: resolve(results)
);
});
}
的类型编写user-defined type guard以将对async.filter()
的呼叫拆分为两个呼叫;或者用intersectFunction()
类似的东西包装arr
函数,以便它接受你想要它的联合,但这些变通方法更庞大并且具有运行时效果,所以我坚持使用{{1}上面的方法。
希望有所帮助;祝你好运!