我编写了以下函数来帮助处理错误
const capture = <T>(
callback: () => T
): { result?: T; error?: Error } => {
try {
return { result: callback(), error: undefined };
} catch (err) {
return { result: undefined, error: err as Error };
}
};
Run Code Online (Sandbox Code Playgroud)
用法示例:
const { result, error } = capture<number>(() => foo());
if (error) badPath();
console.log("hooray we got a result", result)
Run Code Online (Sandbox Code Playgroud)
然而 TypeScript 编译器会抱怨:
Object is possibly 'undefined'. ts(2532)
const result: number | undefined
Run Code Online (Sandbox Code Playgroud)
我理解为什么编译器会抱怨(这是使用可选参数的预期行为)。
然而我想知道是否存在一些可以支持条件返回类型的 TypeScript 恶作剧。
即我们有没有办法指定capture的签名,以便当error不存在时,result推断存在?反之亦然?
capture为{ result: T; error: undefined; } | { result: undefined; error: Error; }。const capture = function<T>(
callback: () => T
): { result: T; error: undefined; } | { result: undefined; error: Error; } {
try {
return { result: callback(), error: undefined };
} catch (err) {
return { result: undefined, error: err as Error };
}
}
const retVal = capture<number>(() => foo());
if (retVal.error)
badPath();
else
console.log("hooray we got a result", retVal.result);
Run Code Online (Sandbox Code Playgroud)
请参阅此游乐场链接。
为了更健壮的实现,我们需要考虑抛出的错误不是 的实例的情况Error。error在这种情况下,检查结果中属性的真实性是不够的。例如,我们可以在这里切换到测试属性error本身是否存在。为此,我们将返回类型更改为{ result: T; } | { error: unknown; }. 一个实现将如下所示:
const capture = function<T>(
callback: () => T
): { result: T; } | { error: unknown; } {
try {
return { result: callback() };
} catch (err) {
return { error: err };
}
}
const retVal = capture<number>(() => foo());
if ('error' in retVal)
badPath();
else
console.log("hooray we got a result", retVal.result);
Run Code Online (Sandbox Code Playgroud)
和操场链接。
这是不可能的,因为 TypeScript 不知道运行时。
我想到的最接近的事情是允许T未定义
(callback: () => T | undefined)
Run Code Online (Sandbox Code Playgroud)
然后将其与 一起过滤error,使代码的其余部分明白result此时是 anumber并且不能是未定义的。
const capture = <T>(callback: () => T | undefined): { result?: T; error?: Error } => {
try {
return { result: callback(), error: undefined }
} catch (err) {
return { result: undefined, error: err as Error }
}
}
const start = () => {
const { result, error } = capture<number>(() => foo())
if (error || !result) {
// something
return
}
// result // here it will be `number`
// (cannot be undefined because we checked)
console.log('hooray we got a result', result)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
130 次 |
| 最近记录: |