
An eco approach to money that makes for a green bank balance
I’m a 24 year-old blogger, writer and consultant living in London.
Signing up takes 2 minutes. Scan this QR code to send the app to your phone.
Or head to the app store:
The benefits of Typescript in a team environment for building and maintaining production-worthy codebases are nothing new. At Cleo we committed early to developing our web and mobile apps with Typescript to give us the safety of static typing when developing our product.
One issue we faced building SPAs with Typescript was additional boilerplate when combined with other paradigms, specifically state management and Redux. The Redux docs[1] give a good starting point for Typescript integration, but their approach remains convoluted. We wanted a way of simplifying this integration to minimise the effort of achieving full type coverage within our codebase.
We'll create a simple app for displaying a customer's transactions to show how we can create type safety alongside Redux.
We define a new type for our transaction, and the store's state.
// types.ts
type Transaction = {
id: string;
description: string;
amount: number;
categoryId: Category['id'];
};
type State = {
transactions: Transaction[];
};
We use the typesafe-actions library to generate typed actions. Defining a new params type for when we dispatch the action.
// actions.ts
import { createStandardAction } from 'typesafe-actions';
import { Transaction } from "../types";
type SetTransactionDescriptionParams = { transactionId: Transaction['id'], description: Transaction['description'] };
export const setTransactionDescription = createStandardAction('SET_TRANSACTION_DESCRIPTION')<SetTransactionDescriptionParams>();
export const deleteTransaction = createStandardAction('DELETE_TRANSACTION')<Transaction['id']>();
The following shows the type safety we get when (incorrectly) dispatching actions:
Where typesafe-action starts to shine.
The dispatched action is typed with the ActionType helper. This builds a union type of the actions:
action: ActionType<typeof transactionListActions>
// evaluates to
{ type: 'SET_TRANSACTION_DESCRIPTION', payload: SetTransactionDescriptionParams } || { type: 'DELETE_TRANSACTION', payload: Transaction['id'] }
We use a switch statement on the action's type, and the getType helper to extract the action's type. This allows the payload's type to be correctly inferred & used within the scope.
// reducer.ts
import * as transactionListActions from './actions';
import { ActionType, getType } from 'typesafe-actions';
import { Category, Transaction } from "../types";
export const transactionListReducer = (state: TransactionListState, action: ActionType<typeof transactionListActions>): TransactionListState => {
switch (action.type) {
case getType(transactionListActions.setTransactionCategory): //getType evaluates to 'SET_TRANSACTION_DESCRIPTION'
// Payload is now typed correctly
const { transactionId, categoryId } = action.payload;
...
case getType(transactionListActions.deleteTransaction):
// Payload is now typed correctly
const transactionId = action.payload;
...
default:
return state;
}
};
The following shows the payload type suggestions we get when within a case.
Simply type the state
// selectors.ts
import { TransactionListState } from "./reducer";
import { Transaction } from "../types";
export const selectTransactions = (state: TransactionListState) => state.transactions;
export const selectCategories = (state: TransactionListState) => state.categories;
export const selectTransaction = (state: TransactionListState, transactionId: Transaction['id'] ) =>
state.transactions.find(transaction => transaction.id === transactionId);
I’m a 24 year-old blogger, writer and consultant living in London.
Lockdown changed us in many ways. Some of us run now, others live off of TikTok food hacks. One or two of us have vouched to never leave the house again. One thing that the pandemic will have changed in all of us though, is our spending. Here are the personality types we see coming out of the woodwork post-lockdown. Tag yourself.
Recessions are out of our immediate control and though it seems unfair, there's still no Sims-esque hack for multiplying our money (we'll let you know as soon as we find one). The good news is that they’re part of the normal economic cycle. Unfortunately, we can’t cancel 2020 (though we can reset it). We can dance in the flames of this dumpster fire of a year once we tackle how to prepare for a recession by optimizing our financial support system. Luckily for you, Cleo’s got some hacks and has your back.