【问题标题】:How to make overloaded higher-order function work correctly with optional arugments in TypeScript?如何使用 TypeScript 中的可选参数使重载的高阶函数正确工作?
【发布时间】:2021-07-12 13:58:45
【问题描述】:

我有一个函数,它返回一个使用 fetch 获取一些数据的承诺:

export function funcWithOptsArgs(a: string, b: number, c?: string): Promise<number> {
  // Some API call.
  return fetch('/blah/blah').then(() => Promise.resolve(10));
}

我编写了一个自定义挂钩来管理来自我的组件的 API 调用。它被定义为一个重载函数,用于接受具有可变数量参数的回调。

export type StreamHook<Data, Callback> = [{ loading: boolean, data: Data | null, error: any }, Callback];

// Custom react hook for API call
export function useAsyncAction<Data>(callback: () => Promise<Data>): StreamHook<Data, () => void>;
export function useAsyncAction<A1, Data>(callback: (a1: A1) => Promise<Data>): StreamHook<Data, (a1: A1) => void>;
export function useAsyncAction<A1, A2, Data>(callback: (a1: A1, a2: A2) => Promise<Data>): StreamHook<Data, (a1: A1, a2: A2) => void>;
export function useAsyncAction<A1, A2, A3, Data>(callback: (a1: A1, a2: A2, a3: A3) => Promise<Data>): StreamHook<Data, (a1: A1, a2: A2, a3: A3) => void>;
export function useAsyncAction<Data>(callback: (...args: any[]) => Promise<Data>): StreamHook<Data, any> {
  // TODO: Implementation
  return {} as any;
}

当我在我的组件中使用它时,它工作得非常好,除了可选参数 - 上面示例中的 c

// Usage
function MyComp() {

  const [data, doFetch] = useAsyncAction(funcWithOptsArgs);

  // Somewhere within the component
  // Works perfectly well.
  doFetch('Harshal', 32);

  // ERROR: Typescript error. Not accepting third argument
  doFetch('Harshal', 32, 'Patil');

}

基本上,它将doFetch 解释为doFetch: (a1: string, a2: number) =&gt; void,同时忽略可选参数。我尝试了许多不同的风格来写签名,但似乎没有任何效果。

有什么解决方案可以解决这个问题?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    你可以尝试使用tuple type in rest parameters:

    export function useAsyncAction<Args extends readonly unknown[], Data>(callback: (...args: Args) => Promise<Data>): StreamHook<Data, (...args: Args) => void> {
      // TODO: Implementation
      return {} as any;
    }
    

    playground link

    【讨论】:

      猜你喜欢
      • 2022-07-01
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 2019-04-20
      • 1970-01-01
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多