Reputation: 385
I am wrapping a function from a library and want the wrapper function to have the same typing as the wrapped function, so that the generics and arguments can be passed through.
The function I am looking to wrap is from the apollo library, named useQuery.
It's declaration looks like this:
export declare function useQuery<TData = any, TVariables = OperationVariables>(query: DocumentNode | TypedDocumentNode<TData, TVariables>, options?: QueryHookOptions<TData, TVariables>): QueryResult<TData, TVariables>;
I want to write a function that wraps useQuery as so:
function wrapper<*generics*>(*args*) {
...
return useQuery<*generics*>(*args*);
}
Can I somehow provide the generics and arguments without having to import the appropriate types?
Can this be done implicitly?
Upvotes: 4
Views: 966
Reputation: 43078
It should be possible to do this. Typescript provides a set of utility types which makes this type of function wrapping, possible.
function wrapper(...args: Parameters<typeof useQuery>) {
// Do something here
return useQuery(...args);
}
See Parameters
. You may also be interested in ReturnType
.
ReturnType
wasn't used in the solution because typescript is able to infer the return type provided return useQuery (...)
is the last thing returned in the function.
Upvotes: 0
Reputation: 327819
There's not currently a way to do this in TypeScript if wrapper
is declared as a function statement. You can get the type of useQuery
with the typeof
type operator, generics and all... but you can't annotate the whole function statement as conforming to it; you'd have to annotate the parameters and return type separately, and the generics explicitly. There is a feature request at microsoft/TypeScript#22063 asking for support for such function statement annotations, but for now they're not part of the language.
On the other hand, if you are okay declaring wrapper
as a variable or constant with a function-typed value, then you can do this easily like this:
const wrapper: typeof useQuery = (...args) => {
// do other stuff here
return useQuery(...args);
}
There's no explicit, manual typing of the generics, parameters, or return types here. And it compiles with no error, indicating that the compiler contextually infers args
to be a rest parameter of the proper generic type, and that the function returns a value of the proper generic type.
Upvotes: 3