How to Write Clearer JavaScript Apps using TypeScript

Daniel Pericich
5 min readApr 27, 2022

--

Photo by Michael Dziedzic on Unsplash

One thing I’ve learned from developing in JavaScript is to be wary of new trends. I’ve seen the next big thing happen over and over whether it’s JQuery to Angular and a divergence of Angular to React and Vue, or the newest flavor of Static Side Rendering with Gatsby or Next.JS. There’s always something new and shiny that someone will want you to build with.

For a while I held this dampened optimism when it came to TypeScript. Why would I want to slow down development to add typing, and why should I spend the time to learn the syntax for yet another language? I had worked on a few TypeScript projects without a great understanding of what TypeScript was beyond the fact that all JavaScript is valid TypeScript so I was safe to just add JavaScript to these TypeScript apps.

Then something changed and I became enthralled in TypeScript. I found an old copy of the seminal video game development tome Basic Computer Games and started rewriting BASIC as JavaScript. These games can be built either using a Node cli or a browser based UI. While some are easy to whip up, others are incredibly involved and required careful planning to avoid the dreaded spaghetti code.

I decided that this was a low stakes opportunity to test out what TypeScript could offer and wow had I been missing out. TypeScript adds typing to JavaScript which converts a dynamically typed language, one in which variables can be created with and returned with any variable type, to a static typed language in which what you see at variable declaration is what you get. This was game changing, especially with working with HTML elements as we’ll discuss later. I can’t imagine going back to regular JavaScript. In this article I will detail how TypeScript makes tasks, such as function declarations and dealing with HTML elements for DOM manipulation, so much clearer.

Intention Packed Function Declarations

One of the most helpful parts of TypeScript is the extra information provided in function declarations. A normal JavaScript function declaration consists of a function name, and optional arguments as shown below:

Figure 1. Vanilla JavaScript Function Declaration.

Because the name of the function is straightforward and the arguments fit the name, this makes sense. However, there are questions left from this. What are the types of the variables? In theory we could accept integers or strings and rely on JavaScript’s ability to coerce types to make our function work. Or we could even change the types manually.

Along with this we don’t know if we are returning any values. A strength and weakness of JavaScript is that it requires explicit return statements. This makes it clear the name of what we are returning, but may require searching if the function is lengthy. Finding the return name doesn’t even touch the idea of what type of value or object we are returning. This is where TypeScript comes in!

Here is a similar function call, written in TypeScript instead of JavaScript:

Figure 2. TypeScript function declaration.

This is so much better! Here we have declared explicitly what types of values we expect for our two arguments, a and b, as well as whether we expect to return a value and what it is. Without looking at any of the body of the function we have a really great idea of how this function may work.

What if we don’t return anything from the function and want to make this clear? This is where the void keyword comes in. Say instead of returning the sum of our two numbers we create a new database record and then return? Then there is no returned value. This is how we’d write our function declaration:

Figure 3. TypeScript declaration with void return.

TypeScript makes function declarations much more maintainable as other developers are easily able to see the IO pipeline for the method they are calling. Everyone appreciates some clearer, cleaner code.

Our Main HTML Element Types

Now that we’ve covered how to use TypeScript to expand the meaning of our functions, let’s look at the different TypeScript HTML element types. It is easy to end up with a mess of unclear spaghetti code when you manipulate the DOM in JavaScript. In my opinion this is due to the lack of clarity of what type of variable you are working with coupled with the extra set of types from working with the DOM.

One of the best features about TypeScript is that it is not shy about yelling at you about incorrect type matches. If you try to call a String method on a variable containing an HTML input element you’ll get a nice red underline. This is great because along with the underline is a hover message that tells you the error, rather than requiring you to start a server to see the error, or having to deal with line by line debugging for silent errors.

To get started let’s look at some of the most common elements:

Figure 4. List of TypeScript HTML element types.

The most basic HTML element for TypeScript is the HTMLElement type. For a while this was inferred by TypeScript if the HTML element was found in the DOM using getElementById, but this has changed to a union of (HTMLElement | null) in later versions of TypeScript. This type can be used for any HTML element, but shouldn’t be when a more specific type is available.

Below the HTMLElement type we can see a number of other types. This list is not all encompassing, but shows a number of more heavily used HTML element types. Included are ways to declare buttons, labels, input fields and images.

The reason I like these types so much is that they clearly show what type of HTML element you are working with and throw nice messages in your editor if you try to access an unsupported attribute. If you try to change the ‘src’ value of an HTMLButtonElement you’ll know right away that you’re making a mistake. The benefits don’t stop here and I highly encourage you to checkout out the full TypeScript DOM types documentation!

Conclusion

I may not have been warm to TypeScript during my first attempts, but I have since become a strict disciple to typing. Especially for Vanilla JavaScript projects in which so much can be occurring with DOM manipulation, I feel that TypeScript is a super tool that all JavaScript developers must add to their developer toolkit.

Notes

https://www.typescriptlang.org/docs/handbook/dom-manipulation.html

https://www.typescriptlang.org/docs/handbook/2/functions.html

--

--

Daniel Pericich
Daniel Pericich

Written by Daniel Pericich

Former Big Beer Engineer turned Full Stack Software Engineer

No responses yet