如果类试图扩展TypeScript中具有重叠通用参数的基类,则强制编译失败

时间:2018-12-05 10:52:13

标签: reactjs typescript

我正在尝试在React中编写一个抽象的基础组件类,该基础类接受子类的通用属性和状态类型PS,然后传递{{ 1}}和P & PBase放入S & SBase的模板类型中。我可以做到,但是随后调用Component只能在this.setState()null上使用。

这是一个简化的示例:

{}

据我所知,问题是编译器无法肯定/** * Simplified version of Component<P, S> */ class Component<S = {}> { setState<K extends keyof S>(state: Pick<S, K> | S | null): void { // set the state }; state?: S; } interface SBase { x: number; } /** * My abstract base class */ abstract class MyComponentBase<S> extends Component<S & SBase> { doSomethingThatSetsState() { // fails: Type 1 is not assignable to type S["x"] this.setState({ x: 1 }); } } 不包含名为S的属性,而x并不包含x

认为的解决方案是强制子类的泛型不与基类的接口共享任何属性。我编写了一些帮助程序类型,如果正在比较的两种类型具有相同的属性,它们将返回number

never

更改上面的示例,以使用它们:

// returns types that T and S both extend
type Same<T, U> = T extends U ? T : never;

// returns never if T and S share any properties in common, else returns T
type NoneInCommon<T, S> = Same<keyof T, keyof S> extends never ? T : never;

// returns T & S if no properties are in common, else never
type Intersect<T, S> = NoneInCommon<T, S> extends never ? never : T & S;

现在的问题是它可以编译:

/**
 * My abstract base class
 */
abstract class MyComponentBase<S> extends Component<Intersect<S, SBase>> {
    doSomethingThatSetsState() {
        // now this succeeds
        this.setState({ x: 1 });
    }
}

它确实使/** * My component class */ class MyComponent extends MyComponentBase<SBase> {} 的{​​{1}}类型为MyComponent的{​​{1}}属性,所以虽然有些理想,但还是不理想。有没有办法强迫编译器识别state是无效类?

0 个答案:

没有答案