Explore TypeScript 5.4: Closure Type Narrowing, NoInfer, and groupBy
This article examines the new TypeScript 5.4 beta features, including improved type narrowing in closures, the NoInfer utility type for better generic inference, the addition of Object.groupBy and Map.groupBy methods, and several important breaking changes to the type system.
Optimizing Type Narrowing in Closures
TypeScript’s type‑narrowing automatically infers more specific types after checks, but the narrowed type is often lost inside closure callbacks. The article shows examples such as uppercaseStrings and getUrls, where the compiler cannot guarantee that a variable like url remains a URL inside Array.map callbacks. TypeScript 5.4 improves this by tracking the last assignment point for let variables used in non‑hoisted functions, allowing safe narrowing when the final assignment is known. The improvement does not apply when a variable may be reassigned inside nested functions.
function uppercaseStrings(x: string | number) {
if (typeof x === "string") {
// TypeScript knows x is a string here
return x.toUpperCase();
}
}
function getUrls(url: string | URL, names: string[]) {
if (typeof url === "string") {
url = new URL(url);
}
return names.map(name => {
url.searchParams.set("name", name); // error without the new analysis
return url.toString();
});
}Utility Type: NoInfer
When generic functions are called, TypeScript infers the type argument from the provided value. This can sometimes lead to overly permissive or overly restrictive calls, as illustrated by a createStreetLight function that accepts a list of colors and an optional default color. Without constraints, a mismatched default color is accepted. Adding a second generic parameter solves the problem but feels awkward.
TypeScript 5.4 introduces NoInfer<T>, a utility type that tells the compiler not to infer T from a particular argument. Wrapping the default‑color parameter with NoInfer<C> restores the desired strictness without extra generic parameters.
function createStreetLight<C extends string>(colors: C[], defaultColor?: NoInfer<C>) {
// ...implementation
}
createStreetLight(["red", "yellow", "green"], "blue"); // error: "blue" not assignableObject.groupBy and Map.groupBy
TypeScript 5.4 adds type declarations for the new JavaScript static methods Object.groupBy and Map.groupBy. Object.groupBy groups an iterable into a plain object whose keys map to arrays of the original elements. Map.groupBy does the same but returns a Map, allowing any type of key.
const array = [0, 1, 2, 3, 4, 5];
const obj = Object.groupBy(array, (num) => (num % 2 === 0 ? "even" : "odd"));
// obj = { even: [0,2,4], odd: [1,3,5] }
const map = Map.groupBy(array, (num) => (num % 2 === 0 ? "even" : "odd"));
// map is a Map with the same groupingWhen using these methods, the target compiler option must be set to esnext (or the appropriate lib configuration) to make the methods available.
Break Changes
Two notable breaking changes arrive in TypeScript 5.4:
More accurate conditional type constraints . Previously, a conditional type like type IsArray<T> = T extends any[] ? true : false could be resolved based only on the generic constraint, leading to unsound assignments. The new analysis considers all possible instantiations of T, producing a union of outcomes when certainty is lacking.
Stricter intersection handling . Intersections between unrelated types now resolve to never. For example, intersecting a generic T extends "abc" | "def" with a number yields never, and template‑string placeholder checks are more precise.
These changes improve type safety but may require code adjustments where older, more permissive behavior was relied upon.
Reference: https://devblogs.microsoft.com/typescript/announcing-typescript-5-4-beta/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
