Write more readable code with TypeScript 4.4
Tags: typescript, webdev
Published: 2021-07-28 20:22:44

**Written by [John Reilly] (https://blog.logrocket.com/author/johnreilly/)** ✏️

An exciting feature is shipping with TypeScript 4.4\. It's called [control flow analysis of aliased conditions](https://devblogs.microsoft.com/typescript/announcing-typescript-4-4-beta/#cfa-aliased-conditions), which is quite a mouthful.

In this post, we'll unpack this new feature and demonstrate how it contributes to improving the readability of code.

## Indirect type narrowing via `const`

On 24 June 2021, [Anders Hejlsberg](https://www.twitter.com/ahejlsberg) closed an issue on the TypeScript GitHub repository with the title "Indirect type narrowing via `const`." The issue had been open since 2016 and it was closed because it was covered by a [pull request](https://github.com/microsoft/TypeScript/pull/44730) addressing control flow analysis of aliased conditional expressions and discriminants.

It's fair to say the TypeScript community was very excited about this, judging from both reactions on the issue:

![Reactions on GitHub to TypeScript's Indirect Type Narrowing](https://blog.logrocket.com/wp-content/uploads/2021/07/reactions-on-github.png)

Not to mention the general delight on Twitter:

![Reactions on Twitter to TypeScript's Indirect Type Narrowing](https://blog.logrocket.com/wp-content/uploads/2021/07/reactions-on-twitter.png)

Zeh's [tweet](https://twitter.com/zeh/status/1408208125572915202) sums up the significance of control flow analysis of aliased conditions quite nicely:

> Lack of type narrowing with consts made me repeat code, or avoid helpfully namef consts, too many times

With this feature, we can write more readable code with less repetition. That's amazing!

## Writing more expressive code with TypeScript 4.4

Rather than diving straight into an explanation of what this new language feature is, let's start instead from the position of writing some code and see what's possible with TypeScript 4.4 that we couldn't tackle previously.

Here's a simple function that adds all the parameters it receives and returns the total. It's a tolerant function and allows you to supply numbers in the form of strings as well. So it would successfully process `'2'` as it would `2`.

This is, of course, a slightly contrived example, but it's a good way to demonstrate the new feature:

```typescript
function add(...thingsToAdd: (string | number)[]): number {
    let total = 0;
    for (const thingToAdd of thingsToAdd) {
        if (typeof thingToAdd === 'string') {
            total += Number(thingToAdd);
        } else {
            total += thingToAdd;
        }
    }
    return total;
}

console.log(add(1, '7', '3', 9))
```

Try it out in the [TypeScript playground](https://www.typescriptlang.org/play?ts=4.3.5#code/GYVwdgxgLglg9mABAQwCaoBQDodQBYxgDmAzgCpwCC6AXIhiVAE6FGIA+iYIAtgEYBTJgEoA2gF1hdbvyGIA3gChEKxABsBURFDhRkaxAF5EABgDcy1cDhN6EBI20FiFaqkRxgT1uSrphCpaqqjBeGFAAngAOAp7eLn7uhsmIAOSMLMSpAUrBeao6egYA1MYAcryCTOHORK7+FvkqAL6IAmokAoFNeYX6iKXxdYmNTc1BiOPBTJogTEh9ahbjivZgJHAaWGpwRBhomACMADRpAOypp6kAzJeIAJzCwkA).

This function, although it works, is not super-expressive. The `typeof thingToAdd === 'string'` serves two purposes:

1.  It narrows the type from `string | number` to `string`
2.  It branches the logic, such that the `string` can be coerced into a `number` and added to the total

You can infer this from reading the code. However, what if we were to rewrite it to capture intent?

Let's try creating a `shouldCoerceToNumber` constant that expresses the action we need to take:

```typescript
function add(...thingsToAdd: (string | number)[]): number {
    let total = 0;
    for (const thingToAdd of thingsToAdd) {
        const shouldCoerceToNumber = typeof thingToAdd === 'string';
        if (shouldCoerceToNumber) {
            total += Number(thingToAdd);
        } else {
            total += thingToAdd;
        }
    }
    return total;
}

console.log(add(1, '7', '3', 9))
```

Try it out in the [TypeScript playground](https://www.typescriptlang.org/play?ts=4.3.5#code/GYVwdgxgLglg9mABAQwCaoBQDodQBYxgDmAzgCpwCC6AXIhiVAE6FGIA+iYIAtgEYBTJgEoA2gF1hdbvyGIA3gChEKxABsBURFDhRkaxAF5EABgDcy1cDhN6EBI20FiFaqkRxgT1uSrphCpaqqvZgjiR4cCBqqADCcEIQAhQAcryCtsZQAJ4ADgKe3i5+7oZliADkjCzEFRbBwTBeDJHRcQlMSanpQgFKDQPauvqIANTGabJMGPisrv71gwC+iAJqJAKBgw06egbjRUTzqIsDS0GI58FMmiBMSLv6FueKoSRwGlhqcEQYaJgARgANJUAOwVEEVADMEMQAE5hMIgA).

This is valid code. However, TypeScript 4.3 is choking with an error:

![TypeScript 4.3 Error](https://blog.logrocket.com/wp-content/uploads/2021/07/doesnt-work-in-typescript-4-3.png)

The error being surfaced is:

```
Operator '+=' cannot be applied to types 'number' and 'string | number'.(2365)
```

What's happening here? TypeScript does not remember that `shouldCoerceToNumber` represents a type narrowing of `thingToAdd` from `string | number` to `string`. So the type of `thingToAdd` remains unchanged from `string | number` when we write code that depends upon it.

This has terrible consequences. It means we can't write this more expressive code that we're interested in and would be better for maintainers of our codebase. This is what TypeScript 4.4, with our new feature, unlocks.

Let's change the playground to use TypeScript 4.4 instead:

![No Error in TypeScript 4.4](https://blog.logrocket.com/wp-content/uploads/2021/07/does-work-in-typescript-4-4.png)

Try it out in the [TypeScript playground](https://www.typescriptlang.org/play?ts=4.4.0-beta#code/GYVwdgxgLglg9mABAQwCaoBQDodQBYxgDmAzgCpwCC6AXIhiVAE6FGIA+iYIAtgEYBTJgEoA2gF1hdbvyGIA3gChEKxABsBURFDhRkaxAF5EABgDcy1cDhN6EBI20FiFaqkRxgT1uSrphCpaqqvZgjiR4cCBqqADCcEIQAhQAcryCtsZQAJ4ADgKe3i5+7oZliADkjCzEFRbBwTBeDJHRcQlMSanpQgFKDQPauvqIANTGabJMGPisrv71gwC+iAJqJAKBgw06egbjRUTzqIsDS0GI58FMmiBMSLv6FueKoSRwGlhqcEQYaJgARgANJUAOwVEEVADMEMQAE5hMIgA).

Now that we've made the switch to TypeScript 4.4, delightfully, we no longer have errors. And as the screenshot shows, the `thingToAdd` variable has been narrowed to a `string`. This is because control flow analysis of aliased conditions is now in play.

We're now writing more expressive code and TypeScript is willing us on our way.

## Read more

This feature is a tremendous addition to the TypeScript language. It should have a significant, long-term, positive impact on how people write code with TypeScript.

To read more, check out the excellent [TypeScript 4.4 beta release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-4-4-beta/#cfa-aliased-conditions). There are also some other exciting features shipping with this release as well.

Thanks very much to the TypeScript team for once again improving the language and making a real contribution to people being able to write readable code.