我正在创建一个更高阶的组件来包装扩展接口的组件:
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
中实现接口?
答案 0 :(得分:4)
TypeScript表示你没有实现你的函数需要其参数的接口,因为你确实没有。
写作时
class A {
//...
}
您可以定义两种类型和一种值。
值,名为A
,是类。这是您使用new
调用来创建对象的函数。
第一个类型,也称为A
,是通过使用{{1}调用类函数创建的对象的类型如上所述。
第二个类型是该类函数的类型。声明一个类不会自动为此类型创建一个名称,但该类型的存在是因为所有值都具有类型。此类型写为new
,因为它是值typeof A
的类型,类的类型。
因此,根据您要完成的任务,您需要
传递A
Test
或者更改你的函数,使它得到一个与类本身类型匹配的对象,而不是它创建的对象
const withClickOutside = clickOutside(new Test);
我怀疑在这种情况下你想要的是后者。
最后,虽然您可能希望将其用于完全有效的文档目的,但我想要注意的是,没有理由声明您的类甚至实现了接口。 TypeScript是一种结构类型语言,所有接口都是通过兼容成员实现的。