When working with TypeScript, it is possible for a generic function to be automatically generated if one of the parameters is a type parameter from another generic function. This can happen without explicitly defining it as a generic.
export function fn<P, R>(cb: (param: P) => R) {
// No explicit generic definition
return (param: P, extra?: unknown) => {
console.log(extra)
return cb(param)
}
}
// `f` is inferred as generic -- const f: <S>(param: S, extra?: unknown) => S
const f = fn(<S>(str: S) => str)
const returned = f("value") // typeof returned is `"value"`
However, there seems to be an issue when trying to achieve this using ordinary types and the infer
keyword.
export type Fn<T extends (param: never) => unknown> = T extends (
param: infer P
) => infer R
? (param: P) => R
: never
// type F = `(param: unknown) => unknown` instead of `<V>(v: V) => V`
type F = Fn<<V>(v: V) => V>
Are there any solutions or details that I might have overlooked?
In continuation with the discussion on the fn
method, it was observed that TypeScript does not infer a generic anymore if the function is overloaded, which may be a problem in specific scenarios.
export function fn<P, R>(cb: { (): ""; (param: P): R }) {
// No explicit generic definition
return (param: P, extra?: unknown) => {
console.log(extra)
return cb(param)
}
}
// typeof f is not generic if function is overloaded
// const f: (param: { value: unknown; }, extra?: unknown) => unknown
const f = fn({} as unknown as { (): ""; <S>(str: S): S })
const returned = f({ value: "value" as const }) // typeof returned is `unknown`
Is there a solution available to resolve this issue?