【问题标题】:Flow inheritance results in incompatible type at runtime流继承导致运行时类型不兼容
【发布时间】:2019-10-22 11:09:19
【问题描述】:

A.js:

// @flow
export interface A {
  propA: string;
  method(): void;
}

B.js:

// @flow
import { A } from "../interfaces/A.js";
export class B implements A {
  propA: string;
  // Additional properties here...

  method() { //do stuff }
  // Additional methods here...
};

main.js:

// @flow
import { A } from "../interfaces/A.js";
import { B } from "../classes/B.js";

export const processA = (w: string, obj: A): string => {
  return processB(w, obj);
};

const processB = (_w: string, _obj: B): string => {
  return _w;
};

错误:Cannot call 'processB' with 'obj' bound to '_obj' because 'A' [1] is incompatible with 'B' [2].

(是的,我知道这些函数中没有使用 A/B obj,这只是一个精简的示例)

我理解为什么会抛出错误,因为在processB 中,不能保证输入_obj 的类型为B,因为它的类型为A。但我想要一个方法,它接受obj: A,然后传递给要求objB 类型的子方法。

有没有办法做到这一点?我通过在调用processB 之前手动检查constructor.name 并使用instanceof 并将声明更改为const processB = (_w: string, _obj: A) 来绕过它。

但似乎有更好的方法。我希望初始方法接受任何实现接口的对象,然后有子方法将输入 obj 强制为扩展该接口的某个类。

【问题讨论】:

    标签: javascript inheritance types casting flowtype


    【解决方案1】:

    我只能考虑使用instanceof,因为Flow 需要某种方式来保证obj 是什么类型。但是,如果您使用的是instanceof,则无需更改processB 即可接受A。例如,

    interface A {
      propA: string;
      method(): void;
    };
    
    class B implements A {
      propA: string;
      // Additional properties here...
      propB: string;
    
      method() { 
        // do stuff
      }
      // Additional methods here...
    }
    
    class C implements A {
      propA: string;
      // Additional properties here...
      propC: string;
    
      method() {
        // do stuff
      }
      // Additional methods here...
    }
    
    function processA(w: string, obj: A): string {
      if (obj instanceof B) {
        return processB(w, obj);
      } else if (obj instanceof C) {
        return processC(w, obj);
      }
    
      throw new Error('Unsupported implementation of interface A');
      // or just return a default string
    };
    
    function processB(w: string, obj: B): string {
      return w + obj.propB;
    };
    
    function processC(w: string, obj: C): string {
      return w + obj.propC;
    }
    

    Try Flow

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-29
      • 2012-05-08
      • 1970-01-01
      • 1970-01-01
      • 2018-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多