抽象反应组件状态中的TypeScript交集类型导致只读错误

时间:2017-11-23 16:19:34

标签: reactjs typescript

我一直在尝试在React中创建一个抽象组件,而不会过多地破坏TypeScript类型系统的规则。根据React的类型,如果在组件的构造函数中设置了state,则它必须是完整的(分配了所有必需的属性)。一种选择是让子类设置整个状态,包括其父类定义的值。为了避免可能产生的重复,我尝试将其设置为使子类可以将此信息传递给抽象类。这导致Readonly错误对我来说没什么意义。这是我正在使用的代码:

import * as React from 'react';

function intersect<T1 extends Object, T2 extends Object>(o1: T1, o2: T2): T1 & T2 {
    let merged: any = {};
    // Do anything to merge objects.
    return merged;
}

interface AbstractState {
    example: boolean;
}

abstract class IntersectionStateComponent<S> extends React.Component<undefined, AbstractState & S> {
    constructor(props: undefined, childState: S) {
        super(props);
        let baseState: AbstractState = {
            example: true
        };
        this.state = intersect(baseState, childState);
    }

    render() {
        return <div></div>
    }
}

abstract class NonIntersectComponent extends React.Component<undefined, AbstractState> {
    constructor(props: undefined) {
        super(props);
        let state: AbstractState = {
            example: true
        }
        this.state = state;
    }

    render() {
        return <div></div>;
    }
}

NonIntersectComponent的构造函数中,当设置状态时,不会发生错误。将AbstractState分配给Readonly<AbstractState>会被视为有效。另一方面,IntersectionStateComponent将无法编译,声称:

IntersectionProblem.tsx(19,9): error TS2322: Type 'AbstractState & S' is not assignable to type 'Readonly<AbstractState & S>'.

交叉点类型在这里有什么不同?

1 个答案:

答案 0 :(得分:0)

这可以解决问题:

MacBook-Pro ~ % rsync -aE --exclude '.__Sync__.*' ~/YouTube/ "/Volumes/YouTube/"
rsync: mkstemp "/Volumes/YouTube/Logic Pro X vs Ableton Live/Logic Pro X vs Ableton Live.fcpbundle/.__Sync__.s0JZGG" failed: Permission denied (13)

MacBook-Pro ~ % rsync -aE --exclude '*.__Sync__.*' ~/YouTube/ "/Volumes/YouTube/"
rsync: mkstemp "/Volumes/YouTube/Logic Pro X vs Ableton Live/Logic Pro X vs Ableton Live.fcpbundle/.__Sync__.MLazTM" failed: Permission denied (13)

MacBook-Pro ~ % rsync -aE --exclude '/*.__Sync__.*' ~/YouTube/ "/Volumes/YouTube/"
rsync: mkstemp "/Volumes/YouTube/Logic Pro X vs Ableton Live/Logic Pro X vs Ableton Live.fcpbundle/.__Sync__.V4fkBM" failed: Permission denied (13)

请记住,您正在执行的操作是反模式。 React建议在继承上使用合成。

”“在Facebook,我们在成千上万个组件中使用React,但我们没有 发现了建议使用组件的任何用例 继承层次结构。”

更多信息:https://reactjs.org/docs/composition-vs-inheritance.html