flowtype - Typing conditional properties with union -


i have following method defined on custom component es6 class takes object component property. if property instance of component assigns ref else creates new instance el , opts properties :

setref({ id, component, el, opts = {}, props = {} }: refconstructortype | refinstancetype): promise<component> {     let ref: component;      if (component instanceof component) {           ref = component     } else {         ref = new component(el, opts);     } }        

my type definitions refconstructortype , refinstancetype are:

type refinstancetype = {|     component: component,     id: string,     props?: {} |};  type refconstructortype = {|     component: typeof component,     id: string,     el: element,     opts ?: {[option_ke: string]: string},     props ?: {} |}; 

anyway flowtype complaining:

86:     setref({ id, component, el, opts = {}, props = {} }: refconstructortype | refinstancetype): promise<component> {                     ^^^^^^^^^ component. type incompatible 86:     setref({ id, component, el, opts = {}, props = {} }: refconstructortype | refinstancetype): promise<component> {                     ^^^^^^^^^ class type: component  src/index.js:86 86:     setref({ id, component, el, opts = {}, props = {} }: refconstructortype | refinstancetype): promise<component> {                     ^^^^^^^^^ class type: component. type incompatible 86:     setref({ id, component, el, opts = {}, props = {} }: refconstructortype | refinstancetype): promise<component> {                     ^^^^^^^^^ component  src/index.js:86 86:     setref({ id, component, el, opts = {}, props = {} }: refconstructortype | refinstancetype): promise<component> {                                 ^^ property `el`. property not found in 86:     setref({ id, component, el, opts = {}, props = {} }: refconstructortype | refinstancetype): promise<component> {                                                                                 ^^^^^^^^^^^^^^^ object type  src/index.js:86 86:     setref({ id, component, el, opts = {}, props = {} }: refconstructortype | refinstancetype): promise<component> {                                     ^^^^ property `opts`. property not found in 86:     setref({ id, component, el, opts = {}, props = {} }: refconstructortype | refinstancetype): promise<component> {                                                                                 ^^^^^^^^^^^^^^^ object type 

any hint on how solve this?

update 26/07/2017

following suggested pattern ended following refined code:

setref(refcfg: refconstructortype | refinstancetype): promise<component> {      let ref: component;      if (!isplainobject(refcfg)) {         throw new error('invalid reference configuration');     }      if (refcfg.component instanceof component) {         ref = refcfg.component;     } else if (typeof refcfg.component === 'function' && refcfg.el) {         const { el, opts, component } = refcfg;         ref = new component(el, opts); //eslint-disable-line new-cap     } else {         throw new error('invalid reference configuration');     }     // .... } 

this pretty complex situation, safe way around not de-structure.

you're putting flow in position you're asking create variable component type component | typeof component , asking if union type valid against refconstructortype.component , valid against refinstancetype.component:

  • component == component | typeof component?
  • typeof component == component | typeof component?

basically, destructuring, implicitly fails "one in, out": https://flow.org/en/docs/types/unions/#toc-union-types-requires-one-in-but-all-out.

that's why you're seeing flow complain twice.

once fix that, other errors going solved making sure flow can accurately discriminate between different conditions in if/else.


Comments

Popular posts from this blog

networking - Vagrant-provisioned VirtualBox VM is not reachable from Ubuntu host -

c# - ASP.NET Core - There is already an object named 'AspNetRoles' in the database -

ruby on rails - ArgumentError: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true -