≪ Today I learned.
RSS購読
    公開日
    タグ
    TypeScript
    著者
    ダーシノ

    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),
    }