如何在typescript中扩展React类

时间:2017-05-06 06:46:27

标签: javascript reactjs typescript

这是一个简单的例子:

interface BaseProps {
    name: string;
}

class BaseClass<P extends BaseProps> extends React.Component<P, void> {

}

interface SuperProps {

}

class SuperClass extends BaseClass<SuperProps> {

} 

我希望SuperClass默认为this.props.name。但是现在,我收到了编译错误,说Type 'SuperProps' does not satisfy the constraint 'BaseProps'.Property 'name' is missing in type 'SuperProps'.

我做错了什么?我意识到我可以做SuperProps extends BaseProps但这在这里似乎是多余的。

2 个答案:

答案 0 :(得分:3)

class BaseClass<P extends BaseProps> extends React.Component<P, void>

其中<P extends BaseProps>表示扩展BaseProps的任何有效类型均可分配给BaseClass。这就是泛型的工作原理。

现在,当你做

interface SuperProps {

}

class SuperClass extends BaseClass<SuperProps> {

} 

您指定的类型SuperProps未延伸BaseProps。这就是你得到错误的原因。

要克服错误,正如您所说,您需要扩展BaseProps接口,或者您可以使用交集类型。如果使用交集类型,那么完整示例将如下所示:

export interface BaseProps {
    name: string;
}

class BaseClass<P> extends React.Component<P & BaseProps, void> {

}

interface SuperProps {

}

class SuperClass extends BaseClass<SuperProps> {
    render(): JSX.Element {
        return (
            <div>
                {this.props.name} {/* Won't throw an error*/}
            </div>
        );
    }
}

您可以阅读有关高级类型here的更多信息。

答案 1 :(得分:0)

现在假设您无法修改 BaseClass(第 3 方代码)以使其采用泛型类型,即

class BaseClass extends React.Component<BaseProps, void> {

}

您仍然应该能够使用扩展的 prop 类型重新定义 BaseClass,如下所示:

const SuperClass = BaseClass as React.ComponentClass<
  BaseProps & {
    somethingElse: string;
  }
>;

完整例如其中 SomeInput 实际上支持 autoFocus 道具,但它导出的道具类型 defs 不支持:

import { Input as SomeInput, InputPropsType as SomeInputPropsType } from 'somewhere';

const Input = SomeInput as React.ComponentClass<
  SomeInputPropsType & {
    autoFocus?: boolean;
  }
>;

// Now passing `autoFocus` prop to `Input` should be fine