Sitemap

What’s new in TypeScript 5.6

5 min readJul 31, 2024
Press enter or click to view image in full size

TypeScript 5.6 beta has been released, introducing several powerful new features that aim to catch common programming errors and enhance support for iterables. These updates not only improve code safety but also bring new capabilities to developers, helping to streamline the development process. In this article, we’ll explore these beta updates, discussing how they can be beneficial for your projects and potentially enhance your coding experience once the full version is released.

Iterator Helper Methods: Bringing Array Methods to Iterables

Iterables and iterators are fundamental to JavaScript, enabling the traversal of collections. However, many developers have found themselves missing methods like map, filter, and reduce on iterables. TypeScript 5.6 addresses this by introducing helper methods for iterables, inspired by a recent ECMAScript proposal.

For instance, you can now use map directly on a generator function:

function* positiveIntegers() {
let i = 1;
while (true) {
yield i++;
}
}

const evenNumbers = positiveIntegers().map(x => x * 2);

for (const value of evenNumbers.take(5)) {
console.log(value);
}

This feature extends to methods like keys(), values(), and entries() on Maps and Sets, making it easier to work with these data structures in a more functional style. For example, you can invert the keys and values of a Map:

function invertKeysAndValues<K, V>(map: Map<K, V>): Map<V, K> {
return new Map(
map.entries().map(([k, v]) => [v, k])
);
}

Additionally, you can create custom iterators by extending the new Iterator object:

class Zeroes extends Iterator<number> {
next() {
return { value: 0, done: false } as const;
}
}

const zeroes = new Zeroes();
const ones = zeroes.map(x => x + 1);

You can also adapt any existing Iterables or Iterators into this new type with Iterator.from:

Iterator.from(…).filter(someFunction);

Introducing BuiltinIterator for Enhanced Type Safety

TypeScript’s new BuiltinIterator type provides a more accurate type model for native iterable iterators. This type ensures that methods like map and take are available on iterators produced by standard JavaScript constructs. Here's how you can leverage this new type:

function invertKeysAndValues<K, V>(map: Map<K, V>): Map<V, K> {
return new Map(map.entries().map(([k, v]) => [v, k]));
}

Moreover, the introduction of BuiltinIteratorReturn and the --strictBuiltinIteratorReturn flag enhances the type safety of iterators, helping to prevent errors such as accessing properties on potentially undefined values.

Disallowed Nullish and Truthy Checks

Have you ever written a regex and forgotten to call .test(...) on it, or accidentally used => instead of >= in a comparison? These kinds of mistakes can lead to bugs that are hard to detect but now TypeScript 5.6 makes catching these errors easier than ever.

if (/0x[0-9a-f]/) {
// Oops! This block always runs.
}

TypeScript 5.6 now identifies this kind of expression as always truthy and flags it with an error. Similarly, it catches errors in expressions where the operator precedence is misunderstood, such as:

function isValid(value: string | number, options: any, strictness: "strict" | "loose") {
if (strictness === "loose") {
value = +value;
}
return value < options.max ?? 100; // Error: Right operand of ?? is unreachable
}

These checks ensure your code behaves as intended by catching such issues early during development.

Allowing Arbitrary Module Identifiers

JavaScript modules can export bindings with names that are not valid JavaScript identifiers. TypeScript 5.6 supports this feature, enabling developers to import and use such bindings seamlessly. This is particularly useful for interoperability with other languages and tools that generate code.

const banana = "🍌";
export { banana as "🍌" };

import { "🍌" as banana } from "./foo";
function eat(food: string) {
console.log("Eating", food);
}
eat(banana);

Enhancements in TypeScript 5.6

TypeScript 5.6 introduces several new features aimed at enhancing developer productivity and catching potential errors earlier in the development process. Let’s dive into the key additions and improvements in this release.

— noUncheckedSideEffectImports Option

In JavaScript, side effect imports are often used to execute global behaviors like registering a global variable or adding a polyfill. However, TypeScript’s behavior of silently ignoring unresolved side effect imports could mask potential typos and errors. TypeScript 5.6 introduces the --noUncheckedSideEffectImports option to catch these cases.

When enabled, TypeScript will throw an error if it cannot find a source file for a side effect import. This change ensures that all imports are valid, reducing the chances of silent failures due to typos.

import “non-existent-module”;

For users who need to import assets like CSS files, an ambient module declaration can be used to avoid errors:

// ./src/globals.d.ts
declare module "*.css" {}

— noCheck Option

The --noCheck option allows TypeScript to skip type checking for all input files. This can be particularly useful for separating JavaScript file generation from type-checking, allowing these tasks to be run in parallel.

tsc --noCheck
tsc --noEmit

This approach speeds up the build process by focusing on file generation first and performing a thorough type check later.

Allow — build with Intermediate Errors

In previous versions, using --build mode would halt the build process if any errors were encountered in upstream dependencies. This rigidity often blocked progress on downstream projects. TypeScript 5.6 now allows the build process to continue even if there are intermediate errors, generating output files on a best-effort basis.

This change helps in scenarios like project upgrades, where dependencies can be upgraded incrementally without blocking the entire build process.

Region-Prioritized Diagnostics in Editors

Editing large files in TypeScript could sometimes feel sluggish due to the time taken to check the entire file. TypeScript 5.6 introduces region-prioritized diagnostics, which focuses on the currently visible region of the file in the editor, making quick edits feel more responsive.

In tests, the initial region-based diagnostics took significantly less time compared to full file checks, enhancing the editing experience in large files.

Search Ancestor Configuration Files for Project Ownership

When a TypeScript file is loaded in an editor, the editor searches for the relevant tsconfig.json file. Previously, this search would stop at the first tsconfig.json file found. TypeScript 5.6 continues the search up the directory tree to find other appropriate tsconfig.json files, providing more flexibility in project organization.

Notable Behavioral Changes

  • .tsbuildinfo is Always Written: To support continuous builds and the --noCheck option, TypeScript now always emits a .tsbuildinfo file for any project in a --build invocation.
  • Respecting File Extensions and package.json in node_modules: TypeScript now respects file extensions and package.json settings in node_modules, ensuring correct module resolution and preventing unsafe imports.

Conclusion

TypeScript 5.6 brings significant improvements in code safety, build efficiency, and diagnostics responsiveness. These updates help developers catch errors early, work more efficiently with iterables, and maintain productivity during large-scale builds. Explore these features by trying out the beta or nightly releases of TypeScript 5.6 and experience the enhanced capabilities for yourself. The new features not only streamline the development process but also provide robust tools to prevent common programming errors, making TypeScript an even more powerful tool for developers.

--

--

Onix React
Onix React

Written by Onix React

We are dedicated React and React Native specialists, turning your dreams and ideas into successful projects. 🔗 linktr.ee/reactonix