【发布时间】:2020-02-15 03:04:42
【问题描述】:
是否可以从函数中返回不仅仅是一个 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();
}
根据条件,上面的函数可以返回一个带有{ error: 'string' }的promise或一个对象。我在这里遇到错误: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 '{}'.
我试过用:
const someFunc = async <T>(url: string): Promise<T> | Promise<string> => {}
这会引发错误: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.
我也试过这个变种:
const someFunc = async <T>(url: string): Promise<T | { error: string }> => {}
但是当我使用这个功能时:
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; }'.
使用类型保护更新
If ('access_token' in result) {
console.log(result.access_token);
}
这很好用,使用来自IResponse 接口的access_token。
【问题讨论】:
-
"
async函数声明定义了一个异步函数 — 一个返回AsyncFunction对象的函数。异步函数的运行顺序与通过事件循环的其余代码不同,返回一个隐式Promise作为结果。" (Source) -
你为什么在这里使用泛型?
-
@voiys 因为我会重用这个函数并且取决于端点它会有不同的响应形状?不是很明显吗?
-
@voiys 不管好坏,它是一种常见的模式,函数从网络返回对象以将结果的预期类型指定为类型参数。它并不比类型断言更好,但稍微方便一些。
-
我刚开始学习 ts 所以我想知道:p
标签: typescript