How to use typescript with Cloud Firestore functions and React
typescript + firebase + React = 🔥
Image by lumenbrite from Pixabay
prerequisites: Basic understanding of React and Typescript
Currently, typescript is all the rage and is certainly becoming a mandatory skill javascript developers should know. In this article, you will learn about type inference, constrained generics, iterating over keys from a type and more. I will also demonstrate how these tools work in the context of a React/React Native project that is using Firebase as a backend. The examples I use will be based on a few observations and issues I came across while working on a personal project.
The issue at hand
While working on a React Native app for my portfolio, I stumbled across a typing issue while implementing a feature that allows a user to update their account information. In order to implement this feature, I used the updateDoc method given to us from Firebase. The beauty of this method is it allows developers to update some parts of a document without overriding the whole document. The example below will demonstrate what our function will look like without types. It’s part of an api service layer.
The code below will display the state being passed to the updatedInfo argument.
When I decided to type my updateUser function, I utilized standard typing practices:
I made id a string type
I made the return type a Promise<void>
And I wanted to make sure any values passed to updatedInfo matched my User type
The obstacle appeared when I decided to type updatedInfo with my User type. When I tried to do this, I received the following error:
Argument of type 'User' is not assignable to parameter of type '{ [x: string]: any; }
I could of used the type unknown, but upon further investigation, I learned I could create a type on the fly by iterating over the keys from my User type.
The keyof User syntax will return a union of key values from my User type for typescript to iterate over. After iterating over the User keys, the updatedInfo argument will have a type equal to the original User type as shown below.
Now typescript is happy and we’re completely type safe.
Type inference
lets say we didn’t implement a User type explicitly on our local react state. Instead, we decided to go with type inference by only setting an initial value as seen below.
There’s a drawback to this approach. If I add a value to my state object (i.e.password), typescript wouldn’t throw an error with the current implementation. To remedy this situation, you can use generic constraints on the updateUser function. By adding a generic constraint (example below), we make it “mandatory” for the object being passed to the updatedInfo argument to possess the same keys as my User type.
By adding extends after the generic T, I’m telling typescript that the value of T must be constrained to a certain type. In this example, our generic is constrained to a union of key values given to us via keyof User. Now if I try to add something to my React state that doesn’t match my User model (as demonstrated below), I will receive a typescript error.
A quick note on type inference vs explicit types
As developers, one of the biggest obstacles we will face throughout our career is Company A will use certain standards and practices that Company B wont. This is why I decided to demonstrate two different scenarios and solutions concerning our typing issue. The goal of this article isn’t to make a claim that one is better than the other but to show the nuance approaches to typescript and React. I hope you learned something new. And if you found value from this post, share, comment, or subscribe to my newsletter.
How to use RTK query with Firebase and React Native pt1
Image by Pexels from Pixabay Prerequisite: Basic familiarity with Firebase concepts like collections, documents, and queries In this two part series, you will learn how to implement RTK query in a React Native project backed by Firebase. Part one will teach you how to build an API layer when building mobile/web apps and why you need one. In part two of th…