Help us understand the problem. What is going on with this article?

TypeScriptで型をDIしてFirestore周りの型チェックをnode/browser向け環境にそれぞれ解決する

*こちらの資料 で解決できなかったと記載したfirebase周りの型解決についての記事になります
こちらの資料を元にした記述があるので、目を通してもらえると理解しやすいかと思います

なにがやりたいか

これ

firebaseのFirestoreへのアクセスする処理をfirebase functionsとフロントで使いまわしたい

何が問題か

これ

firestoreの型定義がブラウザ向けとfunctions向けで別物になっていて、ブラウザ向けは lib.dom.d.tsへ依存しているなど、トランスパイル時に両方を満たすうまい方法が見つけられなかった

firebaseのjs向けsdkは、ブラウザ環境で利用するための firebaseパッケージと、node環境で利用するための firebase-adminパッケージがあります。
これらは共に Firestoreクラスの定義を(何故か)それぞれ持っています
またそれらは、例えばServiceWorkerのような環境に依存する値に依存しています

つまり、いわゆるRepository層を作ってそれをfirebase functionsとフロント双方で使おうとするとTypeScriptのトランスパイル時に型検査エラーとなります

今回はこれを解決しました

どうやったか

解決したcommit
https://github.com/sisisin-sandbox/monorepo-tsconfig/commit/ec424adc9dfff71f4450c4ce92c30d75f1c3f67f

(このリポジトリ構成についてはこの辺参考のこと)


  • それぞれの環境向けのtsconfigを用意
  • また、それぞれの環境向けのfirebase.d.tsを用意
node向けfirebase.d.ts
// 別名にしておかないとfirebase変数を参照したときに `firebase` パッケージのものを参照してしまう
import { firestore as adminFirestore } from 'firebase-admin';

declare module 'firebase' {
  export interface MyFirestore extends adminFirestore.Firestore {}
}
ブラウザ向けfirebase.d.ts
import { firestore } from 'firebase';

declare module 'firebase' {
  export interface MyFirestore extends firestore.Firestore {}
}
  • Repositoryは上記で作成した MyFirestore型を使って型付けする
HogeRepository.ts
import { MyFirestore } from 'firebase';

export class HogeRepository {
  constructor(private db: MyFirestore) {}
// 以下略
  • それぞれの環境向けのtsconfigで、 includeに上記型定義ファイルを含めるようにする

概ね以上になります

つまりどういうこと?

何が問題だったかと言うと、型がnode/browser環境下でそれぞれ違うということなので、それぞれの環境用にトランスパイル出来るようにしつつ、型をトランスパイル時に差し替えということをやりました
つまりトランスパイル時に型についてDependency Injectionしたことになりますね!

この構成だと、front,sharedという2つのパッケージをブラウザ向けにトランスパイルしたいので front/tsconfig.json 及び shared/tsconfig.browser.jsoninclude にブラウザ向けfirebase.d.tsを含めるようにして解決。
functionsも同様、といった具合です

そもそもfirebaseの型定義がuniversalを意識して書かれていればこんなことにはならないんですが、まあしょうがないということで。
あまり起こる事象ではないでしょうが、複数環境向けのリポジトリで同様の課題にあたったときに同じアプローチで解決出来ると思います


次回は資料のもう一つの心残り、 functionsから shared/lib/esのimportがあったとき(またはその逆)にトランスパイルエラーにならない をpaths使って解決する編になる気がします(やる気があれば)

opt
"INNOVATION AGENCY" を標榜するインターネット広告代理店。エンジニア組織 "Opt Techonologies" を中心にアドテクetc...に取り組んでいます。
https://opt-technologies.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした