TypeScript提取Promise泛型并返回[Error,T]元组类型实现方案
问题场景
我编写了一个接收Promise<T>类型入参的函数,目前它的返回值类型为Promise<(null | any)[] | (any | null)[]>,希望将其返回类型修改为Promise<[Error, T]>。
初始实现代码:
// ↓ 希望在这里传入提取到的Promise resolve类型 const customAsyncAwait = <T extends Promise<any>>(promise: T) => { return promise .then(res => [null, res]) .catch(error => [error, null]); }
函数调用方式如下:
async function init() { const api = axios.get<Plants[]>('<API_NAME>'); // typeof api = Promise<AxiosResponse<Plants[], any>> const [error, data] = await customAsyncAwait(api); // 目前typeof data = any,期望类型为AxiosResponse<Plants[], any> }
更新
我目前已经实现了符合类型要求的版本,但写法较为冗余,想知道是否有更简洁优雅的实现方式:
const customAsyncAwait = <T>(promise: Promise<T>): Promise<[Error, T]> => { const result: [Error, T] = [null, null]; return promise .then((res) => { result[0] = null; result[1] = res; return result; }) .catch((error: Error) => { result[0] = error; result[1] = null; return result; }); }
简洁实现方案
不需要提前声明result变量,使用as const做常量断言就可以让TS自动识别数组为元组类型,写法非常简洁:
const customAsyncAwait = <T>(promise: Promise<T>) => { return promise .then(res => [null, res] as const) .catch(err => [err, null] as const) as Promise<[Error | null, T | null]>; }
- 这里把返回类型标注为
Promise<[Error | null, T | null]>比Promise<[Error, T]>更严谨:成功状态下error固定为null,失败状态下data固定为null,完全符合实际运行逻辑,不会出现类型提示和实际值不符的问题。 - 调用该函数时TS会自动推导泛型T的类型,不需要手动传入,
data的类型会和传入Promise的resolve值类型完全一致,符合使用预期。
如果一定要严格匹配预期的Promise<[Error, T]>返回类型,只需要替换最后断言的类型即可:
const customAsyncAwait = <T>(promise: Promise<T>) => { return promise .then(res => [null, res] as const) .catch(err => [err, null] as const) as Promise<[Error, T]>; }
内容的提问来源于stack exchange,提问作者Sameer
相关产品推荐
相关产品推荐

