使用泛型Props与State类型扩展React Pure Component及TS编译问题
解决React Pure Component泛型扩展的TypeScript编译问题
我来帮你梳理下这段代码里的几个问题,以及对应的修复方案:
问题1:未定义的类型别名引用
组件B继承A时,你写了A<bProps, bState>,但代码里并没有定义bProps和bState这两个类型别名,应该替换为你已经定义好的IPropsB和IStateB。
问题2:组件A中setState的类型不兼容
组件A的泛型S是IStateA的子类型,当你在doStaff里调用this.setState({ isSleeping: false })时,TypeScript会认为这个参数是Partial<IStateA>类型,但无法确定它是否符合Partial<S>的约束(因为S可能包含更多状态属性)。我们可以通过类型断言或调整泛型默认值来修复。
问题3:泛型约束的冗余设计
组件A本身是基于IPropsA和IStateA的基础组件,不需要让泛型P和S强制扩展这两个接口,而是可以把它们作为泛型的默认值,这样子类可以灵活扩展或直接使用基础类型。
修正后的完整代码
import React from 'react'; // 组件A interface IPropsA { propsForA: boolean; } interface IStateA { isSleeping: boolean; }; // 调整泛型:给P和S设置默认值,保留扩展能力 class A<P extends IPropsA = IPropsA, S extends IStateA = IStateA> extends React.PureComponent<P, S> { doStaff() { // 类型断言告知TypeScript参数符合Partial<S>约束 this.setState({ isSleeping: false } as Partial<S>); } } // 组件B interface IPropsB extends IPropsA { propsForB: string; }; interface IStateB extends IStateA{ isWorking: boolean; }; // 替换为正确的类型名IPropsB和IStateB class B extends A<IPropsB, IStateB> { doStaff() { // 此处状态同时包含IStateA和IStateB的属性,符合Partial<IStateB>要求 this.setState({ isSleeping: false, isWorking: true }); } }
额外简化方案
如果组件A不需要支持任意扩展的Props和State,也可以直接去掉泛型,直接使用IPropsA和IStateA作为组件的Props和State类型,代码会更简洁:
class A extends React.PureComponent<IPropsA, IStateA> { doStaff() { this.setState({ isSleeping: false }); } }
这种方式适合A是固定的基础组件,不需要子类扩展Props/State的场景。
内容的提问来源于stack exchange,提问作者Zou Googi
相关产品推荐
相关产品推荐

