Methods
Result
comes with some built-in methods for interacting with the wrapped value and handling what happens when the Result
is Err
.
Interacting with the value
From our introductory example, we have our parseInt
function with the signature
function parseInt(str: string, radix?: number): Result<number, string>;
Commonly, we use the map
method to transform the value.
const numTimesTwo = parseInt("2")
.map(n => n * 2)
Here, parseInt
returns Ok(2)
, which can then be map
ped as we see fit. In JavaScript, if this were to fail, it would result in NaN
, or not a number
, meaning we would need to work with isNaN
in order to guard against the failure. Here, though, that's been taken care of for us inside of parseInt
and it will return a nice error message, as an Err
containing information about why the parsing failed. How do we then work with this error?
Interacting with the error
Result
also comes with some methods for working with the error we receive. Most notably, errors can be mapped with mapErr
.
const erroredParse = parseInt("foo")
.mapErr(errorMessage => {
return "Oops, we couldn't parse that value!"
})
This can become very useful when we have much more complex return types
enum MathError {
DivisionByZero,
NonPositiveLogarithm,
NegativeSquareRoot
}
type MathResult = Result<number, MathError>;
function div(x: number, y: number): MathResult {
if (y === 0) {
return Err(MathError.DivisionByZero);
} else {
return Ok(x / y);
}
}
function ln(x: number): MathResult {
if (x < 0) {
return Err(MathError.NonPositiveLogarithm);
} else {
return Ok(Math.log10(x))
}
}
function sqrt(x: number): MathResult {
if (x < 0) {
return Err(MathError.NegativeSquareRoot);
} else {
return Ok(Math.sqrt(x));
}
}
In each of these instances, our error could be one of the enum MathError
. This means we can tailor how we handle the error accordingly.
div(1, 0)
.mapErr(err => {
if (err === MathError.DivisionByZero) {
throw new Error("You attempted to divide by zero!")
}
});
ln(-1)
.mapErr(err => {
if (err === MathError.NonPositiveLogarithm) {
throw new Error("Natural log is not defined for values less than 0");
}
});
sqrt(-1)
.mapErr(err => {
if (err === MathError.NegativeSquareRoot) {
throw new Error("The square root of a negative number is imaginary" )
}
})