Поток: невозможно получить this.props.width, поскольку в T отсутствует свойство width - PullRequest
0 голосов
/ 28 января 2019

Я использую Flow для проверки типа в React Native проекте.

Ссылка: https://flow.org/en/docs/types/

У меня есть два файла: SvgRenderer.js и Cartoon.js, где:

Cartoon extends SvgRenderer

Ниже у вас есть их исходный код:

SvgRenderer.js

import React from 'react';
import Svg, { G } from 'react-native-svg';

export default class SvgRenderer<T> extends React.Component<T> {

  width: number;
  height: number;
  scaleFactor: number;

  constructor(props: T) {
    super(props);
  }
  ...
  config(originalSize: number[]) {
    switch (true) {
      case (this.props.width != undefined):
        this.scaleFactor = this.props.width / originalSize[0];
        this.width = this.props.width;
        this.height = originalSize[1] * this.scaleFactor;
        break;
      case (this.props.height != undefined):
        this.scaleFactor = this.props.height / originalSize[1];
        this.width = originalSize[0] * this.scaleFactor;
        this.height = this.props.height;
        break;
    }
  }
}

Cartoon.js

import React from 'react';
import SvgRenderer from './SvgRenderer';

type Props = {
  for: string,
  width?: number,
  height?: number,
};

export default class Cartoon extends SvgRenderer<Props> {

  firstBorder: string;

  constructor(props: Props) {
    super(props);
  }
  render() {
    return ...
  }
}

Моя проблема в том, что при запуске:

$ npm run flow

я получаю:

Error -------------------- src/helpers/SvgRenderer.js:32:24

Cannot get this.props.width because property width is missing in T [1].

     src/helpers/SvgRenderer.js
     29|     this.originalWidth = originalSize[0];
     30|     this.originalHeight = originalSize[1];
     31|     switch (true) {
     32|       case (this.props.width != undefined):
     33|         this.scaleFactor = this.props.width / this.originalWidth;
     34|         this.width = this.props.width;
     35|         this.height = this.originalHeight * this.scaleFactor;

Error -------------------- src/helpers/SvgRenderer.js:33:39

Cannot get this.props.width because property width is missing in T [1].

     src/helpers/SvgRenderer.js
     30|     this.originalHeight = originalSize[1];
     31|     switch (true) {
     32|       case (this.props.width != undefined):
     33|         this.scaleFactor = this.props.width / this.originalWidth;
     34|         this.width = this.props.width;
     35|         this.height = this.originalHeight * this.scaleFactor;
     36|         break;

, как вы можете видеть на следующем изображении:

enter image description here

Я не понимаю, почему Flow говорит (для SvgRenderer):

Cannot get this.props.width because property width is missing in T [1].

, когда я фактически определил: width внутри: Cartoon как вы можете видеть здесь:

type Props = {
  for: string,
  width?: number,
  height?: number,
};

Я знаю: width и height могут быть типами, но они мне нужны вот так.

Любая идеяо том, как настроить код в порядке Flows считает, что все в порядке?

Спасибо!

1 Ответ

0 голосов
/ 28 января 2019

Чтобы разрешить доступ width и height для типа T, поток должен быть уверен, что T действительно имеет эти свойства.Это можно сделать путем определения ограничения для параметра универсального типа:

type Dimensions = { width?: number, height?: number };

class SvgRenderer<T: Dimensions> extends React.Component<T> {
  // ...

  config(originalSize: number[]) {
    if (this.props.width != undefined) {
      this.scaleFactor = this.props.width / originalSize[0];
      this.width = this.props.width;
      this.height = originalSize[1] * this.scaleFactor;
      return;
    }

    if (this.props.height != undefined) {
      this.scaleFactor = this.props.height / originalSize[1];
      this.width = originalSize[0] * this.scaleFactor;
      this.height = this.props.height;
    }
  }
}

** Также обратите внимание на слегка измененный метод config (вместо switch/case используются операторы if) - это позволяет потокууточните тип width/height (исключите undefined), чтобы он позволял вам выполнять арифметические операции (this.props.width / originalSize[0]).В любом случае наличие switch (true) не имеет особого смысла.

Попробуйте рабочий пример здесь

...