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.
