Quantcast
Viewing all articles
Browse latest Browse all 100

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

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

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 っていうライブラリもあります。

終わりだよ〜


Viewing all articles
Browse latest Browse all 100

Trending Articles