Validate defaults
A collection and a default value share a generic type, but only the collection should determine that type.
TypeScript · Type Alias
NoInfer<Type> blocks inference from the wrapped type while remaining identical to Type for other purposes. Use it when one generic argument should establish a type and another should only be checked against it.
NoInfer<T> keeps TypeScript from using the wrapped type position as an inference source. The wrapped type otherwise behaves like T, so it still participates in checking after inference is determined elsewhere.
NoInfer<Type>| Name | Type | Description |
|---|---|---|
Type | type | The type to use while suppressing inference from the wrapped position. |
function createStreetLight<C extends string>(colors: C[], defaultColor?: NoInfer<C>) {
return defaultColor;
}
const color = createStreetLight(["red", "yellow", "green"], "red");
console.log(color);The first argument determines the allowed color union, while NoInfer prevents the optional default color from expanding that union.
A collection and a default value share a generic type, but only the collection should determine that type.
Several arguments can contribute incompatible candidates to a generic type parameter.
An API should preserve a narrow inferred union instead of widening it from a later argument.
NoInfer<T> is a utility type released in TypeScript 5.4. It blocks inference into T, while remaining identical to T for other type-checking purposes.
Follow-up: What problem does it solve in a generic function? It lets one argument establish the generic type and makes another argument conform to that established type instead of widening it.
In a generic function with multiple candidate sources, TypeScript normally infers from values passed to those positions. Wrapping one position in NoInfer prevents that position from contributing inference candidates.
Follow-up: How would you use it for a default value? Infer the element union from the collection parameter, then write the default parameter as NoInfer<C>.
For a street-light helper, C can be inferred from the colors array, while NoInfer<C> on defaultColor requires the default to belong to that inferred union. An invalid default therefore produces an assignability error.
Follow-up: What happens without NoInfer? The default argument may become an additional inference source, allowing an unintended value to influence C.
TypeScript 5.4generic functionstype inferenceutility typescreateStreetLight