Software Development

3 Exciting New Features in TypeScript 5.5

A Much Needed Upgrade

3 Exciting New Features in TypeScript 5.5
This image has been generated by AI.

In the world of TypeScript, new features are constantly added to upgrade the developer experience for all.

And today is no exception, because TypeScript Version 5.5 has been publicly announced!

In this article, we explore 3 game-changing features to prepare you for this new chapter of TypeScript.

Without further ado… Let’s dive right in!


1. Inferred Type Predicates

Before we look at what this means, lets define what type predicates are.

Type Predicates in TypeScript are functions that return a boolean value and are used to narrow down the type of a variable.

Here is an example of a type predicate that narrows down the type of an input of type any to string:

let x = "test"

// Type Predicate denoted by the `is` keyword.
function isString(variable: any): variable is string {
  return typeof variable === "string"
}

if (isString(x)) {
  console.log(x.trim())
}

Now that we understand what a type predicate is, where does the inferred part come in?

Imagine an array of numbers with only a single null value at index 3.

const nums = [1, 2, 3, null, 5].filter((x) => x !== null)

// nums = [1, 2, 3, 5]
// But the type = (number | null)[] still!
  1. We apply the filter function to omit the null value.
  2. We expect the type of nums to become number[] since the filtered array no longer contains a null value.

Unfortunately, this isn’t currently possible, hence the type of nums remains unchanged.

But TypeScript 5.5 fixes this!

In TS 5.5, the filter function implicitly calls a type predicate to precisely infer the type of the resulting array.

Here is an example of how the type predicate may look under the hood:

// Called for each element in the `filter` function
function isNotNull(x: number | null) {
  return x !== null;
}

2. Regex Checking

Another cool feature is the ability to validate regular expressions via the TypeScript type checker.

Here is a great example from the TS 5.5 announcement, where a syntax error is caught in a regular expression:

let myRegex = /@robot(\s+(please|immediately)))? do some task/
//                                            ~
// error!
// Unexpected ')'. Did you mean to escape it with backslash?

Furthermore, this feature is not limited to syntactic checks!

That’s right, the type checker can also catch semantic issues in your regex, such as non-existent backreferences as shown in this example:

let myRegex = /@typedef \{import\((.+)\)\.([a-zA-Z_]+)\} \3/u;
//                                                        ~
// error!
// This backreference refers to a group that does not exist.
// There are only 2 capturing groups in this regular expression.

3. Narrowing Constant Index Accesses

TypeScript is now able to narrow down expressions of the form obj[key] if and only if obj and key are constant.

Here is an adapted example from the official TS 5.5 announcement:

function changeUnkownValue(obj: Record<string, unknown>, key: string) {
  if (typeof obj[key] === "string") {
    // Now okay, previously was error
    obj[key].toUpperCase()
  }
}

Before, you couldn’t infer unknown Record values using indexed access.

In this case, using the typeof keyword would not infer the unknown type, therefore obj[key].toUpperCase() throws an error.

In TypeScript 5.5 this is fixed, and will no longer create issues in your code.

Conclusion

TypeScript 5.5 introduces many intriguing features, most of which are long awaited by the community.

From all these features, I outlined these 3 to emphasize the significance of this much needed upgrade.


If you enjoyed this article, please make sure to Subscribe, Clap, Comment and Connect with me today! 🌐

References

1