reactjs - Escribir una función idéntica a otra función con Typescript
Estoy envolviendo una función de una biblioteca y quiero que la función envolvente tenga la misma tipificación que la función envuelta, de modo que los genéricos y los argumentos puedan pasarse a través.
La función que estoy buscando envolver es de la biblioteca Apollo, llamada useQuery.
Su declaración se ve así:
export declare function useQuery<TData = any, TVariables = OperationVariables>(query: DocumentNode | TypedDocumentNode<TData, TVariables>, options?: QueryHookOptions<TData, TVariables>): QueryResult<TData, TVariables>;
Quiero escribir una función que envuelva useQuery de esta manera:
function wrapper<*generics*>(*args*) {
...
return useQuery<*generics*>(*args*);
}
¿Puedo de alguna manera proporcionar los genéricos y argumentos sin tener que importar los tipos apropiados?
¿Se puede hacer esto de manera implícita?
Respuesta #1
Actualmente no hay una manera de hacer esto en TypeScript si wrapper se declara como una declaración de función. Puedes obtener el tipo de useQuery con el operador de tipo typeof, los genéricos y todo... pero no puedes anotar toda la declaración de la función como conforme a él; tendrías que anotar los parámetros y el tipo de retorno por separado, y los genéricos explícitamente. Hay una solicitud de función en microsoft/TypeScript#22063 que pide soporte para este tipo de anotaciones de declaración de funciones, pero por ahora no forman parte del lenguaje.
Por otro lado, si estás de acuerdo en declarar wrapper como una variable o constante con un valor de tipo función, entonces puedes hacer esto fácilmente así:
const wrapper: typeof useQuery = (...args) => {
// do other stuff here
return useQuery(...args);
}
No hay una escritura explícita y manual de los genéricos, parámetros o tipos de retorno aquí. Y se compila sin error, lo que indica que el compilador infiere contextualmente que args es un parámetro rest del tipo genérico adecuado, y que la función devuelve un valor del tipo genérico adecuado.
Enlace de Playground al código
Respuesta #2
Debería ser posible hacer esto. Typescript proporciona un conjunto de tipos de utilidad que hace posible este tipo de envoltura de funciones.
function wrapper(...args: Parameters<typeof useQuery>) {
// Do something here
return useQuery(...args);
}
Vea Parameters. También puede estar interesado en ReturnType.
ReturnType no se utilizó en la solución porque TypeScript puede inferir el tipo de retorno siempre que return useQuery(...) sea lo último que se devuelva en la función.
