TL;DR
getSanitizedMessage.ts
import firebase from 'firebase';
import 'firebase/functions';
interface GetSanitizedMessageResponse
extends firebase.functions.HttpsCallableResult {
readonly data: {
ok: boolean;
text: string;
};
}
const getSanitizedMessage = async (): Promise<string> => {
const addMessage: firebase.functions.HttpsCallable = firebase
.functions()
.httpsCallable('addMessage');
const result: GetSanitizedMessageResponse = await addMessage({
text: 'messageText',
});
return result.data.text;
};
事始め
Cloud Functions for Firebaseをクライアントアプリから叩く際、HttpsCallableを重宝するのですが、
TypeScriptで型付けする方法がドキュメントになかったため、その備忘録になります。
冒頭に全コードを載せましたが、単純に型拡張するだけです。
型なしで書く
httpCallable()
とはなんぞやという方はこちらを参照してください。
まず、ドキュメントに沿って普通の呼び出しをJSで書くとこんな感じになります。
getSanitizedMessage.js
const getSanitizedMessage = async () => {
const addMessage = firebase.functions().httpsCallable('addMessage');
const result = await addMessage({ text: 'messageText' });
return result.data.text;
};
TSに書き換える
これを型推論せずにTSで書くとこうなります。
getSanitizedMessage.ts
const getSanitizedMessage = async (): Promise<any> => {
const addMessage: firebase.functions.HttpsCallable = firebase
.functions()
.httpsCallable('addMessage');
const result: firebase.functions.HttpsCallableResult = await addMessage({
text: 'messageText',
});
return result.data.text; // textがany型になる
};
このままだとgetSanitizedMessage()
の返り値の型がany
になってしまいます。
result.data.text
がHttpsCallableResult
に定義されていないためです。
このHttpsCallableResult
、内実は
firebase/index.d.ts
export interface HttpsCallableResult {
readonly data: any;
}
のようになっており、要はこれを拡張した型定義を自前で用意すればよいわけです。
型拡張する
CloudFunctionsの実行結果を反映した、レスポンスの型を定義します。
getSanitizedMessage.ts
interface GetSanitizedMessageResponse
extends firebase.functions.HttpsCallableResult {
readonly data: {
ok: boolean;
text: string;
};
}
あとはこれを型として使うだけです。
const getSanitizedMessage = async (): Promise<string> => {
const addMessage: firebase.functions.HttpsCallable = firebase
.functions()
.httpsCallable('addMessage');
const result: GetSanitizedMessageResponse = await addMessage({
text: 'messageText',
});
return result.data.text; // textがstring型になる
};