TypeScript 无法推断承诺类型

TypeScript can't infer promise type

我试图使 axios 请求的响应类型安全,但在使 TypeScript 编译器正确推断类型时遇到问题。考虑以下函数,它只是 returns 一个 axios 请求 returns 在 .then 块中的所需数据,并使用 .catch 块捕获任何错误:

interface ServerResponse {
  data: {
    User_by_pk: User;
  };
}

interface User {
  id: string;
  password: string;
}

function postRequest() {
  return axios
    .request<ServerResponse>({
      method: 'POST',
      url: 'http://example.com',
      data: someData
    })
    .then((res) => {
      return res.data.data.User_by_pk; //User type
    })
    .catch((error: AxiosError<ServerResponse>) => {
      console.log(error.message);
      return null;
    });
}

我本以为这个函数会得到 return 类型的 Promise<User | null> (.then 中编辑的数据 return 的类型是 User),但相反,它得到的是return 输入 Promise<any>。将 null 更改为 undefined 会得到相同的结果。我什至尝试明确说明函数的 return 类型,但是当使用例如 let user = await postRequest(); 调用函数时,变量 user 获得类型 User 而不是预期的 User | null

如果我删除 .catch 块,函数的 return 类型将被正确识别为 Promise<User>,但是一旦我添加 .catch,它就会变成 Promise<any> 而不是 [=11] =].

我进行了一些谷歌搜索,有些人建议使用具有 Maybe 或 Result 类型的库,例如 True Myth,但如果此功能已经内置到带有 Optionals 和 ?运算符(可选链接)。如何让 TypeScript 为我的函数提供正确的 return 类型?

尝试将函数转换为异步

async function postRequest() {
     try {
       const response = await axios.request<ServerResponse>({
           method: "POST",
      url: "http://example.com",
      data: {}
    });
    return response.data.data.User_by_pk;
  } catch (error) {
    console.log(error.message);
    return null;
  }
}

我给了一个运行你在代码沙箱环境中提供的代码,它似乎正在解释预期的类型,看看

https://codesandbox.io/s/typescript-vi1l7?file=/src/index.ts

所以,事实证明我的 tsconfig 中有一个错误,导致文件未包含在内,因此关闭了严格检查。一旦修复,我的原始代码就会推断出正确的类型!因此,如果其他人遇到此问题,请确保已启用严格并且您的文件包含在 tsconfig 的包含部分中。

重现,关闭strict时下面函数的return类型是string,打开strict时是"true" | null。这显然是您想要的行为:)

function test(input: boolean) {
  if (input) return 'true';
  else return undefined;
}