typescript - Extrahovanie funkcie odovzdanej do Promise.catch vytvára typovú chybu


Som nový v Typescripte a snažím sa pochopiť chybu typu. V kóde nižšie, ktorý som zjednodušil, funkcia ok sa skompiluje bez problémov, ale keď vyberiem funkciu handleError von, už sa typ neoveruje. Pokiaľ viem, kód je identický, keďže som len vybral funkciu, ale očividne je tu niečo, čomu nerozumiem. Môžete mi pomôcť pochopiť, prečo sa to deje a či existuje spôsob, ako to opraviť?

Tu je kód, ktorý sa kompiluje bez problémov

  const ok = <T>(): Promise<AxiosResponse<T>> =>
    axios.post<T>('http://example.com', {}, {}).catch(
      (params: AxiosError<T>): Promise<AxiosResponse<T>> => {
        return Promise.reject<AxiosResponse<T>>(params)
      }
    )

A tu je kód, ktorý to nerobí.

  const handleError = <T>(params: AxiosError<T>): Promise<AxiosResponse<T>> => {
    return Promise.reject<AxiosResponse<T>>(params)
  }

  const notOk = <T>(): Promise<AxiosResponse<T>> =>
    axios.post<T>('http://example.com', {}, {}).catch(handleError)

Chyba, ktorú dostávam, je

Type 'Promise<AxiosResponse<T> | AxiosResponse<{}>>' is not assignable to type 'Promise<AxiosResponse<T>>'.
  Type 'AxiosResponse<T> | AxiosResponse<{}>' is not assignable to type 'AxiosResponse<T>'.
    Type 'AxiosResponse<{}>' is not assignable to type 'AxiosResponse<T>'.
      Type '{}' is not assignable to type 'T'.  TS2322

    46 | const notOk = <T>(): Promise<AxiosResponse<T>> =>
    47 |   axios.post<T>('http://example.com', {}, {}).catch(handleError)
  > 48 |
       | ^

Mojím odhadom je, že sa stratili niektoré typové informácie a handleError potrebuje byť informovaný, čo je T, ale nie som si istý, ako to urobiť.

Tu je codesandbox, ak to pomôže pri inšpekcii.

Odpoveď č. 1

Chyba nastáva, pretože blok catch nenahrádza generický typ vo vašej funkcii handleError. Na vyriešenie tohto problému to musíte urobiť manuálne (príklad)

export const notOk = <T>(): Promise<AxiosResponse<T>> =>
  axios.post<T>("http://example.com", {}, {}).catch(error => handleError<T>(error));

Ďalším riešením je vytvoriť predvolený generický typ pre handle error (príklad)

const handleError = <T = any>(
  params: AxiosError<T>
): Promise<AxiosResponse<T>> => {
  return Promise.reject<AxiosResponse<T>>(params);
};