Why does the presence of a Generic in the signature break the type inference

1 week ago 8
ARTICLE AD BOX

This is a known TypeScript inference limitation (tracked in microsoft/TypeScript#47599). The short version: because xx is generic, TypeScript marks the call xx("") as "context-dependent" and defers it to a second inference pass. By that point, R has already defaulted to null and everything downstream breaks. If xx were non-generic, TypeScript would resolve it immediately and infer R = string with no problem.

There are a few ways around it depending on what you control.

Quickest fix: extract params into a typed variable before the call

typescript

const myParams: () => string = xx(""); const res = resource({ params: myParams, loader: (params) => params, });

This breaks the context-dependency before resource even sees it, so TypeScript gets the type right in the first pass.

Or just annotate the generic explicitly

typescript

const res = resource<string, string>({ params: xx(""), loader: (params) => params, });

A bit more verbose but works fine at every call site.

If you are on TypeScript 5.4+, use NoInfer on loader

typescript

interface ResourceOptions<T, R> { params?: () => R; loader: (param: NoInfer<R>) => T; }

This tells TypeScript to only infer R from params and not from loader, which removes the ambiguity. Pair this with the variable extraction above for the most reliable result.

The variable extraction approach is what I would go with day to day since it requires no changes to the type definitions and works on older TypeScript versions too.


Read Entire Article