Typescript`typeof React.Component`不扩展接口?无法定义高阶组件

时间:2017-10-29 15:14:37

标签: reactjs typescript higher-order-components

我正在创建一个更高阶的组件来包装扩展接口的组件:

interface ClickOutsideInterface {
  onClickOutside: (e: Event) => void
}

我创建的工厂需要React.ComponentClass实施ClickOutsideInterface

  function clickOutside<P>(Component: React.ComponentClass<P> & ClickOutsideInterface){    
    return class ClickOutside extends React.Component<P, {}> { 
      /* on click outside invoke Component.onClickOutside  */

      render() {
        return(<div><Component {...this.props} /></div>)
      }
   }
}

为了测试工厂,我实现了一个扩展ClickOutsideInterface

的组件
class Test extends React.Component<TProps, TState> implements ClickOutsideInterface {
  onClickOutside(event: Event): void {
    this.setState({
      closed: true
    })
  }

  render(){
    return(
      <div>{this.state.closed}</div>
    )
  }
}

但是当我在函数clickOutside中使用该组件作为参数时:

const withClickOutside = clickOutside(Test)

我为参数Test收到以下类型错误:

  

类型'typeof Test'的参数不能分配给类型的参数   'ComponentClass&amp; ClickOutsideInterface”。输入'typeof Test'是   不能指定为“ClickOutsideInterface”类型。       'typeof Test'类型中缺少属性'onClickOutside'。

任何想法为什么Typescript认为我没有在Test中实现接口?

1 个答案:

答案 0 :(得分:4)

TypeScript表示你没有实现你的函数需要其参数的接口,因为你确实没有。

写作时

class A {
  //...
}

您可以定义两种类型和一种值。

,名为A,是类。这是您使用new调用来创建对象的函数。

第一个类型,也称为A,是通过使用{{1}调用类函数创建的对象的类型如上所述。

第二个类型是该类函数的类型。声明一个类不会自动为此类型创建一个名称,但该类型的存在是因为所有值都具有类型。此类型写为new,因为它是值typeof A的类型,类的类型。

因此,根据您要完成的任务,您需要

传递A

的实例
Test

或者更改你的函数,使它得到一个与类本身类型匹配的对象,而不是它创建的对象

const withClickOutside = clickOutside(new Test);

我怀疑在这种情况下你想要的是后者。

最后,虽然您可能希望将其用于完全有效的文档目的,但我想要注意的是,没有理由声明您的类甚至实现了接口。 TypeScript是一种结构类型语言,所有接口都是通过兼容成员实现的。