Because TypeScript gets used a lot in React development, understanding it is important for WordPress developers in the Gutenberg-era. There is a reason TypeScript is taking off - it’s really great! In this article, I will show you why by explaining the basics of how you would use TypeScript to display WordPress posts and comparing TypeScript to PHP. I am going to assume you know the basics of React and are familiar with object-oriented PHP.
There is a demo of the code I am showing in this article, working with live data fetched from a Pantheon-hosted site via the WordPress REST API that you can play with as you go through this article.
What Are Types?
Comparing PHP7 types and interfaces to TypeScript types and interfaces
Interfaces establish new “generic” types. Take a look at this class, with no interface:
This class has the type “Post”, but that’s not a standard. Any other class that needed this class, would be strongly coupled to Post. We can reduce this coupling by defining an interface - a contract that setups of the rules of this generic type - and having Post implement it. Here is that interface:
The class Post needs to be refactored to implement the interface:
What is Typescript?
Typescript makes your code more verbose. By investing more time in defining how the code MUST be used, it becomes harder to use it in ways it shouldn’t be used, which should result in fewer bugs and faster development time over the life of the project, long-term. With a properly configured IDE, Typescript also improves the quality of code-autocomplete, which is a major productivity boost.
"Static typing and linting tools like Flow and ESLint can get you a remarkable amount of confidence, and if you're not using these tools I highly suggest you give them a look. That said, even a strongly typed language should have tests. Typing and linting can't ensure your business logic is free of bugs." - Kent C. Dobbs
Quick Start Typescript With React For WordPress Developers
I think the best way to learn a new thing is to build something practical with it. Let’s spin up a quick React app with Typescript and play with some WordPress posts, that way it’s a familiar data structure that we are typing. Typescript has a great quick start that I recommend reading first.
You can create the app and edit it in your browser with Code Sandbox. Follow this link:
Or, if you want to build the app locally, you can create the same thing with one command:
Describing A WordPress Post With Typescript
Let’s start by creating an interface for a WordPress post - as returned by the WordPress REST API. To keep things simple, let’s start with the post id, which is a number, and the title, which is an object with one or more properties.
In this interface, we say that the property “id” MUST be present and it MUST be a number. The property title, we say it MUST be present and it MUST have the property render, which MUST be a string. Also, the object title MAY have a property “raw” - WordPress returns this if the user making the request can edit the post - and if that property is present, it MUST be a string. The “?” after the property name makes it optional, same as in PHP.
Properties of an interface can be defined with an interface. This is helpful as post title, content, and excerpt all have the same “shape”. That’s what interfaces are for, grouping objects with the same shape into reusable types. So, instead of defining content and excerpt by cutting and pasting title, let’s make a new interface and then reuse that interface:
Take a look at this component:
Here is a component that can show a WordPress post that uses this interface. It also accepts a boolean argument to determine if it should show the post content or excerpt:
That hide/show boolean will come in handy later on in this post when I cover typing change handlers.
Looping WordPress Posts With React and TypeScript
With one component to show a post, we can show a loop of posts. This is a good opportunity to show how we can use types in function arguments, and loops. To illustrate this, I will walk through building a component to list posts.
Here is the component with its arguments:
This component accepts one argument - the object “props”. This object is type so that it must contain the property “posts”. This is a generic type defining that the primitive type array MUST contain objects that implement the interface Post. The property "showContent” is a boolean value, that will be used to determine if the post content or the post excerpt is shown. The property toggleShowContent must be a function. This is the function that will be called to change the value of showContent - in the parent component. We define that function’s arguments and return type inline as well. This function must receive exactly one argument, which must be a boolean and it must return void.
To take this one step further lets loop through the array of Post objects. It’s cool that we know this array has to have properly formed data. It allows us to pass these objects to the BlogPost component that we created in the last step without additional validation:
Notice that the function being called by posts.map() has its function argument typed so that it only accepts Post. The typescript interpreter knows that’s safe to use because posts must be an array of Post objects.
Working With Change Handlers
In React, one thing we do a lot is bind functions to change events. When a button is clicked, we want to do something - in this case, call the toggleShowContent function with the opposite of the current value of showContent.
A change handler or on click function is a function that takes an Event object - in React this is abstracted to the Synthetic Event, or other types that inherit from that interface. For our function, we will type the event as a React.FormEvent<HTMLInputElement>.
Typescript tells us how everything fits together. In this case, we are working with a function that receives the synthetic event and then calls the function toggleShowContent with a boolean. We have to do a little bit of work to make the pieces fit together:
Here is another component that uses a callback function - bound to an input change event this time - using the same type. In this case, the callback function expects to be passed a string, which is set from the event’s current value.
Should You Use Typescript For WordPress Development?
Being able to read code written in Typescript is really helpful, whether you use it or not. Personally, I’m using it on fairly low-level stuff only right now. I started using Flow - Facebook’s alternative to Typescript - fairly early on in my React journey. It slowed down both my refactoring time and it slowed down my computer a lot.
Anyway, I think it’s worth learning. And once you’ve learned it, you can decide if the benefits of Typescript are worth it for you. If you want a quick start, take a look at the code sandbox I created while working on this article. It adds live data fetched via the WordPress REST API:
You may also like:
- [BLOG] What Gutenberg Means for Headless/Decoupled CMS
- [WEBINAR] Webinar Recap: Extending Gutenberg with Josh Pollock