简体   繁体   English

返回 Promise 或 String 的异步函数 - Typescript

[英]Async function that returns a Promise or String - Typescript

Is it possible to return not just a Promise from a function?是否有可能不仅从函数中返回一个 Promise?

const someFunc = async <T>(url: string): Promise<T> => {
  const res = await fetch(url);

  if (!res.ok) return { error: 'error text' };
  return await res.json();
}

Depending on the condition, function above can return a promise or an object with { error: 'string' } .根据条件,上面的函数可以返回一个 promise 或一个带有{ error: 'string' } I'm getting an error here: TS2322: Type '{ error: any; }' is not assignable to type 'T'. '{ error: any; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.我在这里收到一个错误: TS2322: Type '{ error: any; }' is not assignable to type 'T'. '{ error: any; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. TS2322: Type '{ error: any; }' is not assignable to type 'T'. '{ error: any; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.

I've tried to use:我试过使用:

const someFunc = async <T>(url: string): Promise<T> | Promise<string> => {}

This throws an error: TS1055: Type 'Promise<T> | Promise<string>' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.这会引发错误: TS1055: Type 'Promise<T> | Promise<string>' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. TS1055: Type 'Promise<T> | Promise<string>' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.

Also i've tried this variant:我也试过这个变种:

const someFunc = async <T>(url: string): Promise<T | { error: string }> => {}

But when i consume this function:但是当我使用这个函数时:

interface IResponse {
  access_token: string;
  refresh_token: string;
  userRoles: string[];
  error: any;
}

const result = await someFunc<IResponse>(url);
console.log(result.access_token); // throws an error
// TS2339: Property 'access_token' does not exist on type '{ error: string; } | IResponse'.   Property 'access_token' does not exist on type '{ error: string; }'.

UPDATE with type guard更新类型保护

If ('access_token' in result) {
  console.log(result.access_token);
}

this works fine, uses access_token from IResponse interface.这工作正常,使用来自IResponse接口的access_token

The return type for an async should be a Promise , but the result type of the Promise can be a union:对于异步的返回类型应该是一个Promise ,但结果类型Promise可以成为工会:

const someFunc = async <T>(url: string): Promise<T | { error: string}> => {
  const res = await fetch(url);

  if (!res.ok) return { error: 'error text' };
  return await res.json();
}

Playground Link 游乐场链接

To use the function result you will need to narrow the type of the result to see if it is an error or the actual result:要使用函数结果,您需要缩小结果的类型以查看它是错误还是实际结果:


interface IResponse {
  access_token: string;
  refresh_token: string;
  userRoles: string[];
}

async function test() {
  const result = await someFunc<IResponse>("url");
  if (!('error' in result)) {
    console.log(result.access_token);
  }
}

Playground Link 游乐场链接

See the section on type guards from the handbook请参阅手册中有关类型保护的部分

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

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