Making Impossible States with fp-ts and TypeScript in a React Application

Rate this content
Bookmark
Slides

Types and Functional Programming are a great combination to get feedback quickly about types that don't make sense and compose functionality to get a desired result. fp-ts is a very powerful library that provides the tools to work with types and functional programming in an outstanding way. Let’s see it in action in a React Application to make it more type safe and composable by defining impossible states that will reduce the possibility of edge cases in our application.

Cristhian Motoche
Cristhian Motoche
8 min
06 Jun, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

The Talk introduces TypeScript and FPTS in a React application, highlighting the benefits of static typing and functional programming. It discusses the concept of impossible states and how to prevent them using type checking. The importance of defining smart constructors and functions around data types is emphasized. Overall, the Talk explores the combination of JavaScript, TypeScript, and FPTS to create robust and error-free applications.

Available in Español

1. Introduction to TypeScript and FPTS

Short description:

Hello, I'm going to talk about making impossible states with TypeScript and FPTS in a React application. I like static typing and functional programming. TypeScript provides a rich type system, and combining it with FPTS offers many features, such as data types for computations and functional helpers. FPTS also provides type classes and typing senses. Let's combine JavaScript and FPTS to make impossible states.

Hello, I'm going to talk about making impossible states with TypeScript and FPTS in a React application.

My name is Cristian Motochi and I am a software developer at Stackbuilders. And here I've been learning about Haskell and PureScript.

And there are two things that I like about these languages that I always try to make good languages or frameworks. First is static typing because that helps me to get errors as I am developing code and if something doesn't type check, OK, I won't be able to execute the code. I would have to fix that first. And functional programming because by composing functions I can define my program. I think the best way to get static typing in a realtification is with TypeScript. The type system is very rich. We have TypeAlysis, TypeUnions, interfaces, TypeVariables, and many more things. And combining TypeScript with Rambda or Rampdas code, we will get functional programming.

And that will be it, right? Nevertheless, recently I came across FPTS, which is a functional programming library that has a lot of features. It provides many things. It offers a lot of data types, like option to represent computations that may or may not exist, computations that may or may not fail, that's needed, nonempty arrays, and also data types to wrap async operations, that may or may not fail as well. And many more types. Also, some functional helpers, like this back function that we have here, which helps to define a data flow from top to bottom without the need of either numeric variables or defining a very long line of code, which may be hard to do. This one goes from top to bottom explaining what it is doing on every step. And the best part of FPTS is that it offers type classes and typing senses. Type classes are a good way to get added volumetricism. Here we have an example of the EnqueueType class with a type variable T, and we need to define an equals method to define a type instance of these type kits. We can define type instances defined in JavaScript objects and VConfig with complete types. We have many type classes defined in FPTS, monoids, functals, applicatives, monads, and many more. Let's combine JavaScript and FPTS to make impossible states, which is something that I learned back with John Feldman in this conference some years ago, as you can see. The purpose is to get compiler errors to avoid undecided states. Let's imagine the following example. We have this form to order a pizza, where we have the main selection and the main ingredient, then the second ingredient, which is optional, and the list of extra ingredients. And the main ingredient is not selected by default at the beginning. So we can think about the following data type to represent the data that we placed in that form. Which may be selected, the other not. A second ingredient, which is optional.

2. Types and State Selection

Short description:

We can have states that we may not want in our application. For example, we don't want the users to have the list of extras if they haven't selected the main ingredient. Let's think about one thing we can do to get a type error if we define this type of state. We have another scenario where the user hasn't selected the main ingredient but they do have selected their second ingredient. So let's come up with a better type that would complain in these cases. Now we can define smart constructors and other functions around this type, and even define type instances for this data type.

And the list of extras. And this type could work, nevertheless. We can have states that we may not want in our application. For example, we don't want the users to have the list of extras if they haven't selected the main ingredient. OK, so we don't want this state to happen. That's because one complaint we'll get at some point with this case.

If we define the type... If we define this type of a slash. So, let's think about one thing we do to get a type error if we define this type of state. OK, we could think about this one. The main ingredient is not going to be only the ingredient, it's going to be the ingredient and the list of extra options. Yeah so if we try to define something like this, with this direct type, this time we will get a type error. And that could be the problem.

However, we have another scenario. Where the user hasn't selected the main ingredient but they do have selected their second ingredient. So that's something that we don't want either. OK, so let's think a little bit more and let's come up with this direct type. Using the time system from TypeScript to get a better type that would complain in the previous cases. So in this case we have a non main ingredient which is a direct type that doesn't have any value. So nothing else can be selected. And a selected name which is going to have the main selection. It could have the second selection or not. And then they are right of extra ingredients. So this type will complain if we try to define this or this is nice. And that's nice. Now we can define smart constructors and other functions around this type. And even we can define type instances for this data type so we can use it later. For example we want to use it with fruits. We can't use it with the real fruits because they use... you know for performance reasons we have changed the object reference and disarm object but that is not gonna help us. We will have to use FPS with the state of fruits which will use the echo instance in order to know if a type has changed if the state has changed on a data type or something like that so we can avoid rerenders in our application. Ok so in conclusion if you like type safety and functional programming JavaScript and FPTS are a good option.