Give Your Brain a Break: 3 Ways TypeScript Leads To Less Cognitive Load Than JavaScript

Give Your Brain a Break: 3 Ways TypeScript Leads To Less Cognitive Load Than JavaScript

ยท

5 min read

Your brain can hold a limited amount of information in working memory.

The same holds true when you're programming. Because of this, it's a good idea to limit distractions when you're developing. Having to divide your attention only makes problem-solving more difficult. A focused mind leads to a better development experience.

Fewer distractions = efficient development

In this post, we'll take a look at how TypeScript leads to fewer distractions than JavaScript.

This might not make sense at face value. TypeScript is a superset of JavaScript with static types. It's more verbose and requires more typing to use it to its fullest abilities.

So why wouldn't it be less efficient?

It turns out that typing is rarely a development bottleneck. Going from 40 wpm (words per minute) to 80 wpm doesn't mean that you'll necessarily be able to develop twice as fast.

Maybe this is true for trivial problems ๐Ÿคทโ€โ™‚๏ธ.

But for nontrivial problems, most of your time is spent understanding existing code and coming up with a solution to the problem in front of you.

So where does TypeScript come into play?

1. Existing TypeScript code is easier to understand

Understanding existing code is a tedious process.

It's time-consuming.

A major culprit comes from reusing existing functions. A good comment or parameter name can help, but most code misses the mark. To understand a function, you have to understand how it's being used.

// JavaScript
function notifyUsers(notification, options) {
    const usersToNotify = getUsers(options);
    // Notify each user
}

// TypeScript
type User = { name: string; email: string; };
type NotificationOptions = {
    filterByUserInfo: (userInfo: User) => boolean;
};

function notifyUsers(notification: string, options: NotificationOptions) {
    const usersToNotify = getUsers(options);
    // Notify each user
}

The difference between these two examples is the types in the second version.

You can probably guess that notification is a string in the JavaScript example. But what about the second parameter? You just know that it supports an arbitrary set of options.

But what goes into those options?

Without type information, you have to inspect the function body. Except in this case, that's not even enough. There's a nested function call. To understand how to use the options, you have to understand the getUsers function as well.

The TypeScript version doesn't have that problem.

The options are well-defined by the NotificationOptions type. The type shows that options is an object with a filterByUserInfo property. That property is a function that returns a boolean.

Great! But there's more.

We also know that filterByUserInfo takes a single argument that is a type of User โ€” an object with a name and email property.

The beauty of this is that you don't have to care about the internal details of the notifyUsers function. This is faster because you aren't wasting time digging through function bodies. You can safely call the function because its signature is explicitly defined.

Yes. You have to spend time upfront to define the types, but you save time whenever you or someone else uses the function in the future.

2. It's safer to refactor TypeScript code

All developers will refactor code at some point in their careers.

TypeScript makes this process reliable. It comes with a compiler that warns you when you miss something.

Let's look at an example of what a refactor might look like in JavaScript vs TypeScript:

// OLD JavaScript
function notifyUsers(notification, options) { /* Do Something */ }

// NEW JavaScript
function notifyUsers(notification) { /* Do Something */ }

// OLD TypeScript
type Notification = string;
type NotificationOptions = { severity: number };
function notifyUsers(notification: Notification, options?: NotificationOptions) { /* Do Something */ }

// New TypeScript
type Notification = { message: string; severity: number; };
function notifyUsers(notification: Notification) { /* Do Something */ }

The function parameters have been grouped into a single object to make it easier to extend in the future.

It's not hard to make this change in the JavaScript version, but it's tedious. How do you know you're not introducing regressions? You have to inspect each instance of the function to determine how it's used.

You need to use context to make sure nothing breaks.

// some-file.js
function someFeature() {
    // Do something
    notifyUsers(notification);
    // Do something else
}

In this case, you need to verify that notification is an object.

3. TypeScript code gives better IntelliSense

Modern developers are spoiled.

Our IDEs are designed to carry us. From autocompletion to in-line error messages, modern development has improved drastically. So why not try to optimize it as much as possible?

One area we can take a look at is IntelliSense.

It's possible to get some level of IntelliSense with JavaScript, but it's nothing close to what you get with TypeScript. The biggest gains are feedback around:

  • Object structure

  • Function parameters

  • Function return types

type User = { name: string; email: string };
type Notification = {
    message: string;
    filterByUserInfo: (user: User) => boolean;
};

function notifyUsers(notification: Notification) { /* Notify */ }

function main() {
    // Do something
    notifyUsers({
        message: 'some notification',
        filterByUserInfo: user => user.email.includes('@test.com')
    });
}

Without the types, you'd be able to guess that message is a string and filterByUserInfo is a function. But there's no way you'd know what arguments are passed to filterByUserInfo.

It's some type of user information, but to find out what's in it, you need to go to the source.

It's even more challenging if you pull the users from a database.

Without a well-defined structure for the user data, you have to inspect the database.

TypeScript doesn't have this problem. You define what's allowed directly in the code. Even better, your IDE gives hints while you develop, so you waste less time and make fewer mistakes.

TypeScript lets you focus on the important things

TypeScript lets you focus on the problem in front of you.

Working with existing code is easier, safer, and more reliable. You can rely on technology to do the heavy lifting. It's less frustrating and more efficient.

Next time you start a new project, consider giving your brain a break and using TypeScript.

ย