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
Post a Comment