I have written the following function to help with error handling
const capture = <T>(
callback: () => T
): { result?: T; error?: Error } => {
try {
return { result: callback(), error: undefined };
} catch (err) {
return { result: undefined, error: err as Error };
}
};
Example usage:
const { result, error } = capture<number>(() => foo());
if (error) badPath();
console.log("hooray we got a result", result)
However the TypeScript compiler will complain:
Object is possibly 'undefined'. ts(2532)
const result: number | undefined
I understand why the compiler is complaining (this is expected behaviour for using optional params).
However I was wondering if there existed some TypeScript shenanigans that could support conditional return types.
i.e. is there a way we could specify capture
's signature such that when error
doesn't exist, result
is inferred to exist? And vice versa?
CodePudding user response:
- Define the return value of your
capture
function as{ result: T; error: undefined; } | { result: undefined; error: Error; }
. - Do not destructure the return type; check its properties instead. TypeScript is not smart enough yet to link the types of distinct variables in this case.
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);
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)
}