TypeScript:类型“T”不满足约束“(...args:any)=>any”

问题描述 投票:0回答:1

我有以下 redux-thunk 动作创建器:

function updateInitiator(form_request_id, { to_recipient }) {
  return (dispatch) => {
    const url = `/some/url`;
    const data = { to_recipient };

    return fetch(url, { method: 'PUT', body: JSON.stringify(data) }).then(() => {
      dispatch(fetchResponses());
    });
  };
}

然后我声明函数的类型:

type UpdateInitiator = typeof updateInitiator;

我正在尝试导出绑定 thunk 操作的类型。简而言之,当 Action Creator 在 React-Redux 中被“绑定”时,它会自动调用

dispatch
返回的函数,然后返回 that 内部函数的返回结果。我正在尝试为这种行为声明一个类型。如果我在没有泛型的情况下这样做,它会起作用:

type BoundUpdateInitiator = (...args: Parameters<UpdateInitiator>) => ReturnType<ReturnType<UpdateInitiator>>;

但是当我尝试为任何绑定函数声明泛型类型时,我遇到了一些麻烦:

type BoundThunk<T> = (...args: Parameters<T>) => ReturnType<ReturnType<T>>;
type BoundUpdateInitiator = BoundThunk<UpdateInitiator>;

这给了我错误:

error TS2344: Type 'T' does not satisfy the constraint '(...args: any) => any'.

236 type BoundThunk<T> = (...args: Parameters<T>) => ReturnType<ReturnType<T>>;
                                              ~

error TS2344: Type 'ReturnType<T>' does not satisfy the constraint '(...args: any) => any'.
  Type 'unknown' is not assignable to type '(...args: any) => any'.
    Type '{}' provides no match for the signature '(...args: any): any'.

236 type BoundThunk<T> = (...args: Parameters<T>) => ReturnType<ReturnType<T>>;
                                                                ~~~~~~~~~~~~~

error TS2344: Type 'T' does not satisfy the constraint '(...args: any) => any'.

236 type BoundThunk<T> = (...args: Parameters<T>) => ReturnType<ReturnType<T>>;
                                                                           ~

我可以模糊地理解

T
可能是函数以外的东西,同样
ReturnType<T>
也可能不是函数,而这种泛型类型可能无法解释这些情况。然而,我无法理解我如何“能够”解释它们。理想的情况是不允许他们这样做。有什么建议吗?

reactjs typescript redux-thunk
1个回答
24
投票

事实上,这就是语言提供的实用程序类型

Parameters<T>

ReturnType<T>
的类型参数本身的指定方式,从而产生您收到的错误。
为了实例化泛型类型,例如 

ReturnType<T>

,使用我们的类型参数,我们的类型参数必须至少与

T
中名为
ReturnType<T>
的类型参数一样受到限制。
通过查看包含 

ReturnType<T>

文件提供的

lib
声明,我们可以确定必须应用于我们自己的类型的最小约束,并找到表达所述约束的正确语法的示例。
type ReturnType<T extends (...args: any[]) => any> =
    // details

不要担心实施(在
=

之后),因为这是一个更广泛的主题。在这种情况下,我们将重点关注在

T
声明中使用
extends
关键字指定的
T
的约束。
因此,为了将 

T declared

BoundThunk<T>
传递到
ReturnType<T>
,我们必须对其进行约束以满足上述要求(请注意,
Parameters<T>
具有相同的约束)。
type BoundThunk<T extends (...args: any[]) => any> =
    (...args: Parameters<T>) => ReturnType<ReturnType<T>>;

但是,我们对 
T

的要求实际上是

more
限制性的,因为我们应用 ReturnType<T> 两次,
ReturnType<ReturnType<T>>
,这意味着
T
是一个高阶函数,在本例中是一个返回函数的函数。
因此我们将相应地完善我们的约束

type BoundThunk<T extends (...args: any[]) => (...args: any[]) => any> = (...args: Parameters<T>) => ReturnType<ReturnType<T>>;

通过上述调整,进一步将
T

限制为返回另一个函数的函数,从而使我们能够编写

ReturnType<ReturnType<T>>
    

© www.soinside.com 2019 - 2024. All rights reserved.