如何编写类方法React.Component的类型注释?

时间:2018-08-13 17:56:51

标签: reactjs typescript

我想在多个地方重用React.Component的类方法的类型注释。因此,我想提取类方法的类型注释,并将其创建(并导出)为单独的类型。在下面的示例中(handleClick()类方法):

export type Amount: number;
interface State {
    amount: Amount;
}

class Example extends React.Component<{}, State> {
    handleClick(e: React.FormEvent<HTMLInputElement>) {
        // some code
    }
    render() {
        <AnotherComponent
            amount={this.state.amount}
            handleClick={this.state.handleClick}
        />
    }
}

它的类型注释应提取到:

export type HandleClickType = (e: React.FormEvent<HTMLInputElement>) => void;

我以为我可以像这样轻松地放回该类型:

class Example extends React.Component<{}, State> {
    handleClick : HandleClickType (e) {}
}

我该怎么做?我要这样做的原因是,当我将函数作为道具传递而必须重新键入类型注释时,是为了防止代码重复。

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

您可以执行此操作,但函数将是字段而不是方法,存在细微差别。

首先解决。您的函数类型还可以,但是初始化字段的方法不正确:

class Example extends React.Component<{}, State> {
    handleClick:HandleClickType = (e) => {
        this // is Example
    }

    handleClickFunction:HandleClickType = function(e) {
        this // this is any and might cause an error depending on compiler settings
    }
}

第一个字段初始化为箭头函数,因此从类上下文中捕获this,访问this将按预期工作。第二个示例使用一个常规函数,该函数将this键入为any,这意味着在noImplcitThis下访问它实际上会导致错误(如果没有此选项,则访问this将会是任何类型,因此不会被选中)

我们可以通过使用显式注释或在函数类型中添加额外的参数来帮助推断函数内部的this来解决此问题

export type HandleClickType = (e: React.FormEvent<HTMLInputElement>) => void;
export type HandleClickTypeWithThis<T> = ( this: T, e: React.FormEvent<HTMLInputElement>) => void;
class Example extends React.Component<{}, State> {
  handleClickFunctionWithInfferedThis: HandleClickTypeWithThis<this> = function (e) {
    this // this is now example
  }
  handleClickFunctionWithExplcitThis: HandleClickType = function (this: Example, e) {
    this // this is now example
  }
}

出于完整性考虑,我提到了function选项,如果您不确定箭头功能可能会最好地工作。

现在介绍方法和函数字段之间的细微差别。除了两者将使用不同的图标代码完成功能外,最大的区别是该方法仅分配一次并分配给原型,而对于字段,将为每个对象创建闭包并将其分配给实例。这将导致更多的内存使用情况,这在某些情况下可能很重要。但是,无论如何,如果您需要捕获this,就不会有太大关系,因为无论如何您都会找到一个新的闭包。