Result型でエラーハンドリングする
Result型とは、成功と失敗の両方を表現できる型で、それぞれのハンドリングがしやすくなる。
type Result<T, E = Error> =
| { ok: true, value: T }
| { ok: false, error: E }
サンプルコード
// CustomError(ArgumentError、DivideByZeroError)
function divide(x: number, y: number): Result<
number, // OKのときの型
ArgumentError | DivideByZeroError // Errorのときの型
> {
if (x === y) {
return { ok: false, error: new ArgumentError() }
}
if (y === 0) {
return { ok: false, error: new DivideByZeroError() }
}
return { ok: true, value: x / y }
}
// run
const ans = divide(x, y)
if (ans.ok === true) {
console.log(ans.value)
}
if (ans.ok === false) {
if (ans.error instanceof ArgumentError) {
console.error(ans.error.name) // ArgumentError
}
if (ans.error instanceof DivideByZeroError) {
console.error(ans.error.name) // DivideByZeroError
}
}
理想形
Result型を使うときは、パターンマッチが使いたくなる。
enum Result<T, E> {
Ok(T),
Err(E),
}
match get_value(true) {
Ok(result) => println!("success: {}", result),
Err(msg) => println!("failure: {}", msg),
}