传递union类型的props来响应需要联合中一种类型的子组件

时间:2018-05-21 12:02:31

标签: javascript reactjs typescript ecmascript-6

在Typescript + React中。我有两个具有接口指定的特定类型的组件(模块)。另外,我有一个父组件,它带有一个带有指定为props的联合的数组。

子组件:

第一单元

interface IModuleOneProps {
  moduleOneSpecificProp: string;
  module_type: sting;
  commonProp: string;
}

const ModuleOne: React.SFC<IModuleOneProps> = props => {
  return (
    <p>{moduleOneSpecificProp + " " + commonProp}</p>
  );
};

export default ModuleOne;

第二单元

interface IModuleTwoProps {
  moduleTwoSpecificProp: string;
  module_type: sting;
  commonProp: string;
}

const ModuleTwo: React.SFC<IModuleTwoProps> = props => {
  return (
    <p>{moduleTwoSpecificProp + " " + commonProp}</p>
  );
};

export default ModuleTwo;

包含模块数组的容器组件,可以是以下两种类型:

interface IContainerModuleProps {
modules: Array<
    IModuleOneProps | IModuleTwoProps
  >;
}

class ContainerModule extends React.Component<IContainerModuleProps> {

  public render() {
    const module = this.props.modules[1];
    switch (module.module_type) {
      case 'module_one':
        return <ModuleOne {...module} />;
      case 'module_two':
        return <ModuelTwo {...module} />;
    }
  }
}

但在渲染组件时,TypeScript不会让我传播module。它抱怨类型。

Type '{ commonProp: string; moduleOneSpecificProp: string; }' is not assignable to type 'IntrinsicAttributes & IModuleOneProps & { children?: ReactNode; }'.
  Type '{ commonProp: string; moduleTwoSpecificProp: string; }' is not assignable to type 'IntrinsicAttributes & IModuleOneProps & { children?: ReactNode; }'.
    Property 'moduleOneSpecificProp' is missing in type '{ commonProp: string; moduleTwoSpecificProp: string; }'.

有没有快速解决方法,我没有在这里看到?或者我必须在将prop对象(module)传递给子组件之前重建它?

1 个答案:

答案 0 :(得分:1)

如果你这样做,你需要将let id, name; //declare variables export default class App extends React.Component { constructor(props) { super(props); this.state = { id: 0, name: '' }; let { params } = this.props.navigation.state; id = params ? params.id : null; //set var if params.id exists else null name = params ? params.name : null; } componentDidMount() { this.setState({ id: id, name: name }); } render() { return( <View> { this.state.id } { this.state.name } </View> ); } } 属性定义为字符串文字类型(只有一个值的字符串类型),然后module_type将正确键入警告:

switch

完全可以使用字符串文字的枚举来避免依赖于魔术字符串:

interface IModuleOneProps {
    moduleOneSpecificProp: string;
    commonProp: string;
    module_type: "module_one"
}
interface IModuleTwoProps {
    moduleTwoSpecificProp: string;
    commonProp: string;
    module_type: "module_two"
}
interface IContainerModuleProps {
    modules: Array<
    IModuleOneProps | IModuleTwoProps
    >;
}

public render() {
    const module = this.props.modules[1];
    switch (module.module_type) {
        case 'module_one':
            return <ModuleOne {...module} />;
        case 'module_two':
            return <ModuleTwo {...module} />;
    }
}

然后在界面和渲染方法中使用enum MODULE_NAME { MODULE_ONE, MODULE_TWO }