type predicateでFirebaseのエラーハンドリングをする
前回type predicate使う場面が出てきてテンション上がって記事を書いた
その直後にもう一つtype predicate使う場面が出てきたのでメモ
TSのバージョンを4.4に上げた時にエラーになる部分が出てきたのでそれに対応するために使用した
背景
TSを4.4にアップデートしたらエラー吐くようになった
内容見たらcatchの中のerrorオブジェクトが今までanyに推論されてたのがstrict: trueだとunknownに推論されるようになったらしい。
エラーハンドリングでerror.message
とかやってたのがerrorがunknownになったことで怒られるようになった
try {
...
} catch (error) {
console.error(error.message) // エラー
...
}
narrowingによる対応
解決策としては下記のようにnarrowingしてやればok
errorはErrorオブジェクトであることを教えてあげればmessageプロパティが使える形になる
try {
...
} catch (error) {
if (error instanceof Error) console.error(error.message)
...
}
基本これでokなんだけど、一箇所firebaseのエラーハンドリングの部分だけ困った
try {
...
} catch (error) {
if (error.code === 'auth/account-exists-with-different-credential') {
// エラーハンドリング
}
}
元々これはfirebaseのドキュメントにも書いてある書き方なんだけど、Errorオブジェクトにはcodeプロパティがないので、他の部分と同じようにinstanceof Error
とするだけじゃだめだった
type predicateを使う
narrowingでerrorオブジェクトがcodeというプロパティを持つことを示したい
そんな時に使えるのがぼくらのtype predicate
以下のようにすると行けた
type FirebaseError = {
code: string
message: string
name: string
}
const isFirebaseError = (e: Error): e is FirebaseError => {
return 'code' in e && 'message' in e
}
try {
...
} catch (error) {
if (
error instanceof Error &&
isFirebaseError(error) &&
error.code === 'auth/account-exists-with-different-credential'
) {
// エラーハンドリング
}
}
Firebaseから型がexportされてるか分からなかったので、codeを持つ型を自分で定義してtype predicateしてやればerrorがFirebaseErrorに推論されるのでerror.code
が通るようになった
type predicateの使い方完全に理解した!!
まとめ
TSおもしれー!!!(2回目)