简体   繁体   English

函数参数返回类型的打字稿类型推断

[英]Typescript type inference for function parameter's return type

in my react project I declare my api requests with this pattern:在我的反应项目中,我用这种模式声明了我的 api 请求:

export type LoginApiResponse = {
  token: string,
  user: User
}

export function login(email: string, password: string): Promise<LoginApiResponse> {
  return AuthService.signinWithEmailAndPassword(email, password)
}

and I consume them through a custom hook我通过自定义钩子消耗它们

export function useApi<T, Fn extends (...args: any[]) => Promise<T>>(
  fn: Fn
) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState();
  const execute = async (...params: Parameters<Fn>) => {

    setLoading(true);

    try {
      const result = await fn(...params);
      setLoading(false);
      return result;
    } catch (err) {
      console.warn("sideEfect execution error", err, JSON.stringify(err));
      setError(err);
      setLoading(false);
      throw (error);
    }
  };
  return { loading, execute, error };
}

with an implementation like this像这样的实现

const loginExecutor = useApi<LoginApiResponse, typeof api.login>(api.login) const loginExecutor = useApi<LoginApiResponse, typeof api.login>(api.login)

In this way I encapsulate loading and error state for a given api request, plus I have full typing support通过这种方式,我封装了给定 api 请求的加载和错误状态,而且我有完整的打字支持

在此处输入图片说明

在此处输入图片说明

THE QUESTION问题

Now my question is: is there a way to take advantage of typescript type inference to infer the return type and parameters type of the fn function in order to be able to write现在我的问题是:有没有办法利用 typescript 类型推断来推断 fn 函数的返回类型和参数类型,以便能够编写

useApi(api.login)

instead of代替

useApi<LoginApiResponse, typeof api.login>(api.login)

While keeping the same strong typing?同时保持相同的强类型?

I see that your example infers everything except a response.我看到您的示例推断出除响应之外的所有内容。 It has the following type:它有以下类型:

const loginExecutor = useApi(login)

const loginExecutor: {
    loading: boolean;
    execute: (email: string, password: string) => Promise<unknown>;
    error: string;
}

Try on TS Playground试玩TS Playground


I updated useApi to extract args and return type separarly:我更新了useApi以分别提取 args 和返回类型:

export function useApi<A extends any[], T>(
  fn: (...args: A) => Promise<T>
)

So now we get following type:所以现在我们得到以下类型:

const loginExecutor = useApi(login)
const loginExecutor: {
    loading: boolean;
    execute: (email: string, password: string) => Promise<LoginApiResponse>;
    error: string;
}

Try on TS Playground试玩TS Playground


Please note that my examples were tested on TS >= 4.请注意,我的示例在 TS >= 4 上进行了测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM