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