Article summary
When writing a function, I often want to return either the successful value or an error. Given that my current project is in TypeScript, we came up with a nice little Either pattern for returning successes or errors.
Since writing this pattern, I’ve found myself reaching for it often. We define a Result to be either T or an Error. By using a simple isError
helper, we can prove our result to TypeScript and maintain type safety.
type Result<T> = T | Error;
export type Type<T> = Result<T>;
export function isError<T>(result: Result<T>): result is Error {
return result instanceof Error;
}
export function isSuccess<T>(result: Result<T>): result is T {
return !isError(result);
}
This approach is especially nice since it is type-safe and doesn’t require any wrapping object. It’s a simple snippet, but very useful; try it out on your next TypeScript project! One caveat: this pattern will not work with an any
type (it will report all things as success).
Usage
import * as Result from 'result';
type Thing = {
name: string
}
function doIt(): Result.Type<Thing>{
if(true) {
return {name: "Todd"};
} else {
return new Error("boom")
}
}
const errorOrSuccess = doIt();
if(isError(errorOrSuccess)) {
// now we can know that we have an error
console.log(errorOrSuccess.message)
} else {
console.log(errorOrSuccess.name)
}