Ввод функции идентично другой функции с помощью Typescript

avatar
Alex Gourlay
8 августа 2021 в 19:14
142
2
2

Я создаю оболочку для функции из библиотеки и хочу, чтобы функция-оболочка имела тот же тип, что и обернутая функция, чтобы через нее можно было передавать дженерики и аргументы.

Функция, которую я хочу обернуть, находится в библиотеке apollo с именем useQuery.

Это объявление выглядит следующим образом:

export declare function useQuery<TData = any, TVariables = OperationVariables>(query: DocumentNode | TypedDocumentNode<TData, TVariables>  options?: QueryHookOptions<TData, TVariables>): QueryResult<TData, TVariables>;

Я хочу написать функцию, обертывающую useQuery следующим образом:

function wrapper<*generics*>(*args*) {
    ...
    return useQuery<*generics*>(*args*);
}

Могу ли я как-то предоставить дженерики и аргументы без необходимости импортировать соответствующие типы?

Можно ли это сделать неявно?

Источник

Ответы (2)

avatar
jcalz
9 августа 2021 в 01:02
1

В настоящее время нет способа сделать это в TypeScript, если wrapper объявлен как оператор функции. Вы можете получить тип useQuery с оператором типа typeof, дженериками и всем остальным... но вы не можете аннотировать весь оператор функции как соответствующий ему; вам придется аннотировать параметры и возвращаемый тип отдельно, а дженерики явно. По адресу microsoft/TypeScript#22063 есть запрос на поддержку таких аннотаций операторов функций, но пока они не являются частью языка.

С другой стороны, если вы можете объявить wrapper как переменную или константу со значением, типизированным функцией, то вы можете легко сделать это следующим образом:

const wrapper: typeof useQuery = (...args) => {
  // do other stuff here
  return useQuery(...args);
}

Здесь нет явного ручного ввода дженериков, параметров или возвращаемых типов. И он компилируется без ошибок, что указывает на то, что компилятор контекстуально выводит args как остаточный параметр надлежащего универсального типа, и что функция возвращает значение надлежащего универсального типа.

Ссылка на код игровой площадки

jcalz
9 августа 2021 в 16:01
0

вы можете подумать о том, чтобы принять ответ.

avatar
smac89
9 августа 2021 в 02:12
0

Это должно быть возможно сделать. Typescript предоставляет набор служебных типов, которые делают возможным этот тип переноса функций.

function wrapper(...args: Parameters<typeof useQuery>) {
  // Do something here
  return useQuery(...args);
}

См. Parameters. Вас также может заинтересовать ReturnType.

ReturnType не использовался в решении, потому что typescript может сделать вывод о типе возвращаемого значения, если return useQuery (...) — это последнее, что возвращается в функции.