Patrick Desjardins Blog
Patrick Desjardins picture from a conference

TypeScript 5.4 NoInfer Utility Type

Posted on: 2024-05-09

The latest TypeScript version, 5.4, brings a new utility type. The type NoInfer is a utility type that helps to prevent the inference of a type variable in a generic function. This utility type is proper when using generic types in a function, but TypeScript doesn't want to infer the type.

Why Use NoInfer?

The NoInfer is a utility type that narrowly scopes the type inference. The use case is when a generic has many options, and a second argument needs to be part of the first type.

For example, let's have two functions: countBefore and count. Both functions take an array and a value to count. The countBefore function uses T[] and T. The count function uses T[] and NoInfer<T>. The NoInfer utility type prevents TypeScript from inferring the type of T. Meanwhing that the second argument must be a subset of the first argument and not inferring that it can be any type of the first argument. In the example below, the count() does not compile.

type SetValue = 1|2|3|4|5;

function countBefore<T extends SetValue>(s:T[], p:T): void{
 console.log(s.filter(f=>f ===p).length);
}

function count<T extends SetValue>(s:T[], p:NoInfer<T>): void{
 console.log(s.filter(f=>f ===p).length);
}

count([1,2,3], 5);
countBefore([1,2,3], 5);

The reason is that count has the NoInfer, which tells TypeScript to be wiser. The NoInfer sets the type of the second argument to be a subset of the first argument. In this case, 5 is not part of the array [1,2,3] and TypeScript complains. Before, the second argument type would be the same as the first one, which allows 1|2|3|4|5. However, with NoInfer the type is 1|2|3.

Conclusion

The NoInfer utility type prevents cases where options are selected that are not part of a whole type. It is the case for a union of types or types extending a larger type. The NoInfer tells the transpiler to analyze the type.