简体   繁体   中英

Type inference, currying and generics not returning the expected type

still learning the type sorcery that is generics and I can't figure out why r here:

const paginateQueryWith = <P, O, T extends (a: O) => P>(fn: T) => async (c: O) => {
  return fn(c)
}

const r = paginateQueryWith((a: string) => parseInt(a))

Doesn't return the expected type:
(c: string) => Promise<number>
but instead returns
(c: unknown) => Promise<unknown>

I've shared it with a few people who also assumed that it would correctly infer the type of the parameter and the return type.

What's going on?
Can what I'm trying to do here be done?

Generic type parameters are easiest to infer when they are simply the type of one of the arguments; in this case, T is the type of your function's argument, so it could be inferred easily at the call-site, but P and O are not directly the types of your function's arguments and cannot be easily inferred.

Instead of building the function type T from its parameter and return type as separate type parameters, you can use Parameters and ReturnType to extract these, which means they don't need to be type parameters at all:

const paginateQueryWith =
    <T extends (arg: any) => any>(fn: T) =>
        async (c: Parameters<T>[0]): Promise<ReturnType<T>> => {
    return fn(c)
}

// (c: string) => Promise<number>
const r = paginateQueryWith((a: string) => parseInt(a))

Playground Link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM