LoginSignup
12
11

More than 3 years have passed since last update.

🔵 TypeScript - Goみたいに「例外を投げない」ためのライブラリを作った

Last updated at Posted at 2019-03-18

2020/5/2追記: Liftsというライブラリを作りました。こっちの方が使いやすいです→ https://qiita.com/yarnaimo/items/1d1c33196c0b6b43c11a

先日この記事を読みました。
「例外を投げない」という選択肢をとる言語

Go や Scala では、例外を JavaScript のように throw して catch することが推奨されず、多値返却や Either でエラーも戻り値として返すアプローチがとられるという内容です。

TypeScript でも同じようなことがしたかったので fp-ts を使って作ってみました!!!🎉🎉

TrySafe
https://github.com/yarnaimo/trysafe

yarn add trysafenpm i -S trysafe でインストールできます🙃

どっかで見たことあるような名前ですが気のせいです。

使い方

import { Try, TryAsync } from 'trysafe'

const result = Try(() => {
    return document.querySelector('a')!.href // 要素が見つからない場合はエラーが throw される
})

// この場合 result の型は Either<Error, string>

if (result.isLeft()) {
    // ここでは result.value の型は Error
    console.error(result.value.message) // -> エラーメッセージ
    return
}

// ここでは result.value の型は string
console.log(result.value) // -> href の値

Try には引数のない関数 () => T を渡します。

Try の戻り値の型は fp-ts の Either<Error, T> で、これは Left 型と Right 型の Union Type です。

渡された関数の中でエラーが throw された場合は Left、成功した場合は Right が返され、.isLeft().isRight() で判別することができます。

async 関数を渡したい場合は TryAsync を使います。

const result = await TryAsync(async () => {
    return await fetch('http://example.com')
})

普通の try-catch と比べていいところ

「エラーが起きる可能性」を明示できる (try-catch を忘れることがない)

例えばこんな関数があったとします。

async function getUsers() {
    return fetch('/users')
}

この関数はエラーを throw する場合があるので上流で catch すべきですが、特にネストが深い場合などは忘れてしまう可能性もあります。

async function getUsers() {
    return TryAsync(async () => fetch('/users'))
}

Try で囲むと、エラーが発生した場合も外には throw されずに戻り値で返されるのでその心配はありません。

エラーが握りつぶされにくい

エラーを上流で処理するような設計にしやすいので、下流でエラーを握りつぶしてしまう可能性も減るのではないかと思います。

あとがき

今回の内容とは関係ないですが、fp-ts といえば実行時に型チェックをするための io-ts っていうライブラリもあります。

終わりだよ〜

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11