How To Migrate Firebase Cloud Functions — JavaScript To TypeScript

Firebase cloud functions support several languages and execution environments including Javascript and Typescript. Recently I did a JavaScript to Typescript migration and followed the recommended migration steps.
Why Typescript?
By understanding JavaScript, TypeScript saves you time catching errors and providing fixes before you run code.
Firebase cloud functions written in Javascript do not allow to define type annotations such as return types.

This was a bummer for me. Typescript code for Firebase cloud functions allow to define return types, so I started the migration to TypeScript.
CLI command prompts
firebase init functions is the main CLI command to convert such a Javascript codebase to Typescript. Apart from the documented prompts I experienced these additional questions:

Not to start from scratch with the (es)lint setup is just great.
Firebase imports & Typescript options
The existing javascript imports did not follow typescript conventions. I did change several import statements similar to this:

Also I enriched the firebase generated file tsconfig.json based on https://stackoverflow.com/a/63434005 :

The option esModuleInterop was really helpful with import issues like these:

Node.js Runtime
Cloud functions support at the time of writing 3 node.js runtimes:
https://firebase.google.com/docs/functions/manage-functions#set_nodejs_version
NVM is a handy command line tool to switch between different node runtimes. It’s a CLI tool that can help to match one of the supported runtimes. Just call nvm use [node] to switch the node version of your choice.
Linting
I spend the most time fixing eslint errors to be able to deploy. This way I realized how relaxed javascript code can be.
The javascript code in functions/lib directory was not touched in the migration attempt so far. However, I got several linter findings about that code. I deleted all javascript files in that directory. Those files will be generated while deploying anyway.
Several functions eventually returned http status codes. Typescript helped my to make sure a dedicated http status codes is returned for all conditions.

Cloud Firestore triggers enable functions code to deal on firestore document changes. Functions’ parameter for those functions include change and context. If context is not used in the function body, eslint warns about no-unused-vars. I deleted the context parameter for all functions.

I decided not to fix some eslinter errors, rather I ignore those. I came accross javascript code lines that caused multiple eslinter errors. https://stackoverflow.com/a/56714489 list options how to disable multiple linter errors:

Last but not least I had to deal with quite some eslinting issues that may come up not only in a javascript to typescript migration but also when you change the linter rules.

Function parameter types
The javascript code base I worked with did not define function parameter types. VS Code’s feature Infer all types from usage fixed this issue for most of the cases. Type inference is a real time saver.


Time safe string compare
Http headers’ verification was done with tsscmp based on github.com/suryagh/tsscmp. The respective typescript code looks significantly different and is inspired by github.com/IBM/diem/…/verifysignature.ts.
Originally published at https://www.lotharschulz.info.