使用 Typescript 键入与另一个函数相同的函数

Posted

技术标签:

【中文标题】使用 Typescript 键入与另一个函数相同的函数【英文标题】:Typing a function identically to another function with Typescript 【发布时间】:2021-10-12 16:05:21 【问题描述】:

我正在包装一个库中的函数,并希望包装函数具有与被包装函数相同的类型,以便可以传递泛型和参数。

我要包装的函数来自 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*);

我能否以某种方式提供泛型和参数而不必导入适当的类型?

这可以隐式完成吗?

【问题讨论】:

【参考方案1】:

应该可以做到这一点。 Typescript 提供了一组实用程序类型,使这种类型的函数包装成为可能。

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

Parameters。你可能也对ReturnType感兴趣。

ReturnType 未在解决方案中使用,因为 typescript 能够推断返回类型,前提是 return useQuery (...) 是函数中返回的最后一件事。

【讨论】:

【参考方案2】:

如果wrapper 被声明为function statement,则目前没有办法在 TypeScript 中执行此操作。您可以使用the typeof type operator、泛型和所有类型获得useQuery 的类型……但您不能annotate 整个函数语句都符合它;您必须分别注释参数和返回类型,并显式注释泛型。 microsoft/TypeScript#22063 有一个功能请求,要求支持此类函数语句注释,但目前它们不是语言的一部分。

另一方面,如果您可以将wrapper 声明为具有函数类型值的变量或常量,那么您可以像这样轻松地做到这一点:

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

这里没有显式手动键入泛型、参数或返回类型。并且它编译没有错误,表明编译器contextually推断args是正确泛型类型的rest参数,并且函数返回正确泛型类型的值。

Playground link to code

【讨论】:

你可以考虑accepting the answer。

以上是关于使用 Typescript 键入与另一个函数相同的函数的主要内容,如果未能解决你的问题,请参考以下文章

Typescript:这种用于键入函数的键入方法是啥?

Typescript:在这种情况下如何使用泛型类型键入函数?

TypeScript:如何正确键入一个接受承诺并按原样返回该承诺的函数

在 TypeScript 中键入匿名对象的属性

TypeScript:如何为函数中的任何键键入对象剩余分布

样式化组件 + Typescript:如何键入 css 辅助函数?