TypeScript:类型'T'不满足约束'(... args:any)=>任何'

时间:2020-03-27 03:24:36

标签: reactjs typescript redux-thunk

我有以下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;

我正在尝试导出绑定重击动作的类型。简而言之,当动作创建者在react-redux中被“绑定”时,它会自动调用以dispatch返回的函数,然后返回内部函数那个的返回结果。我正在尝试为此行为声明一个类型。如果我没有泛型的话,它会起作用:

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>也可能不是函数,并且这种通用类型可能无法解决这些情况。但是,我在理解如何可以解释这些问题时遇到了麻烦。理想情况下,不允许他们这样做。有什么建议吗?

1 个答案:

答案 0 :(得分:5)

为此,我们将使用通用类型约束。

实际上,这是指定提供的实用程序类型Parameters<T>ReturnType<T >所提供语言的类型参数的方式,从而导致错误。

为了使用我们的类型参数实例化通用类型,例如ReturnType<T>,我们的类型参数必须至少与ReturnType的类型参数一样严格地受到约束。 通过查看ReturnType<T>的定义,我们可以确定需要应用的最小约束以及相关的语法

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的要求实际上有严格的限制,因为我们两次ReturnType两次应用ReturnType<ReturnType<T>>,这意味着T更高排序函数,在这种情况下为返回函数的函数。

因此,我们将相应地改善约束条件

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