如何在TypeScript中合并单独的函数声明?

时间:2017-10-14 16:29:56

标签: typescript

我正在尝试在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>'.

那么,我怎样才能将这些声明合并为一个?

谢谢你。

1 个答案:

答案 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}上面的方法。

希望有所帮助;祝你好运!