【问题标题】:Flow types and Polymorphism流类型和多态性
【发布时间】:2019-08-30 01:41:28
【问题描述】:

下面的组件接受Field 对象的fields 数组。 Field 类由 SelectboxField 扩展(和其他字段,但这是目前代码中的字段)。该组件确定字段的类型并呈现该字段的特定组件。特定组件,例如 SelectboxFieldView 将特定类型的字段 (SelectboxField) 作为道具。

// @flow
import React, { Component } from "react";
import { Text, View } from "react-native";
import Field from "../models/fields/Field";
import SelectboxFieldView from "../components/SelectboxFieldView";
import SelectboxField from "../models/fields/SelectboxField";

type Props = { fields: Field[] };
type State = {};

class FieldsRenderer extends Component<Props, State> {
  render() {
    const MockFields = [
      this.props.fields.find(f => f.type === "selectbox") || new Field()
    ]; 

    // const fields = this.props.fields
    const fields = MockFields
    return (
      <View>
        {fields.map((field, i: number) => {
          switch (field.constructor) {
            case SelectboxField:
              const selField: SelectboxField = field;  // ERROR HERE
              return <SelectboxFieldView key={i} field={selField} />;
            default:
              return <Text key={i}>A Field</Text>;
          }
        })}
      </View>
    );
  }
}
export default FieldsRenderer;

我在field这个词上指出的行上出现了一个流错误,说:

Cannot assign field to selField because Field is incompatible with SelectField`

无论是否有selField 的显式类型定义,都会出现此错误。

我也尝试过 Type Casting 表达式:

 switch (field.constructor) {
            case SelectboxField:
              (field: SelectboxField);
              return <SelectboxFieldView key={i} field={field} />;

但它说“无法将字段转换为 SelectboxField,因为字段与 SelectboxField 不兼容`

这似乎不对:

// @flow

class Field {
  title: string;
  type: string;

  static fromApiFormInfo(formInfo: Object): Field {
    const field = new Field();
    field.title = formInfo.title;
    field.type = formInfo.type;
    return field;
  }
}

export default Field;
// @flow
import Field from "./Field";

class SelectboxField extends Field {
  placeholder: string;
  options: string[];

  static fromApiFormInfo(formInfo: Object): SelectboxField {
    const base = new SelectboxField();
    const baseField = super.fromApiFormInfo(formInfo);
    const field: SelectboxField = Object.assign(base, { ...baseField });
    field.options = formInfo.options;
    field.placeholder = formInfo.placeholder_text;
    return field;
  }
}

export default SelectboxField;

有没有办法解决这个问题?

【问题讨论】:

  • 你的错误提到了SelectField,但你的帖子都是关于SelectboxField的。这是一个问题吗?如果您可以精简一个可以在flow.org/try 中重现的示例,那就太好了。
  • 一定是我在抄写错误时打错了

标签: reactjs react-native flowtype


【解决方案1】:
switch (field.constructor) {
  case SelectboxField:

Flow 不能将其处理为type refinement,以便理解fieldSelectboxField。你会想做的

if (field instanceof SelectboxField) {
  return <SelectboxFieldView key={i} field={field} />;
} else {
  return <Text key={i}>A Field</Text>;
}

【讨论】:

  • 谢谢,这行得通!这太糟糕了,因为switch 干净多了。
猜你喜欢
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
  • 2017-01-14
  • 1970-01-01
  • 2011-07-10
  • 2016-01-10
  • 1970-01-01
  • 2013-12-23
相关资源
最近更新 更多