我有一个操作,使用 API 响应进行一些计算,如下所示
try {
const data = await FooService.request();
someCalculation1(data as FooServiceData);
someCalculation2(data as FooServiceData);
someCalculation3(data as FooServiceData);
someCalculation4(data as FooServiceData);
} catch(err) {
console.log(err)
}
关键是这很不正常,而且不是那么可读,每次都重新输入as SomeServiceData
,但我相信需要这样做,因为我的FooService.request
有这种实现
request(): Promise<SomeServiceData | Error> {
return callApi()
.then(res => {
return res as SomeServiceData;
})
.catch(err => {
console.log(err)
return Error("Some error")
})
}
由于该函数可以返回每个SomeServiceData
或Error
它迫使我强制转换类型。但关键是data
永远不会是Error
型,因为如果是,它就不会是,错误将被抛出,err
将是Error
型。但是我不知道如何避免这种选角。
我认为将服务从Promise
格式更改为async
/await
格式,但我认为它根本不会改变行为。
一方面,您可以键入data
本身而不是参数表达式:
const data = (await FooService.request()) as FooServiceData;
但听起来你想在request
的调用者中捕获,而不是request
本身 - 在request
内保留.catch
,以便在出现错误时,调用方将处理它。(您当前的代码会导致data
成为实际错误,因为.catch
会导致解析为返回错误的 Promise。
尝试:
try {
const data = await FooService.request();
someCalculation1(data);
// ...
} catch(err) {
console.log(err)
}
request() {
return callApi()
.then(res => {
return res as SomeServiceData;
});
}
甚至
request() {
return callApi() as Promise<SomeServiceData>;
}
但关键是数据永远不会是错误类型,因为如果是,它就不会是,错误将被抛出,错误将是错误类型。
这是不正确的。 承诺可以解析为实现中的Error
对象,因为您在request()
中捕获了 API 错误,并在发生这种情况时返回new Error
。 当您catch
时,您将防止抛出错误。
您需要检查data
类型以区分Error
和SomeServiceData
,而不是操作中的try/catch
块。 您可以将if ( data instanceof Error )
用作类型保护,并且在两个分支中打字稿知道它只能是该类型。
const data = await FooService.request();
if ( data instanceof Error ) {
// data is Error
console.log(data.message);
} else {
// data is SomeServiceData
someCalculation1(data);
}
或者,如果您想在操作中保留try/catch
块,则需要更改FooService.request()
以便它抛出错误而不是捕获它。 基本上,您只需要在两个地方之一捕获错误。 一旦被抓住,它就不会再被扔了。
const FooService = {
async request(): Promise<SomeServiceData> {
return await callApi() as SomeServiceData;
}
}
现在承诺只能解决SomeServiceData
.