reactjs - Flow type errors due to missing data prop after applying apollo's graphql() HOC -
after reading post how easy add flow types graphql
infused object figured i'll give try. since post in june flow has had major upgrade 0.53 , can't basic example work class component. i'm not sure if it's upgrade or in original definition react-apollo isn't working out.
question: how class version of component work?
here's example code:
// @flow import * react 'react'; import gql 'graphql-tag'; import { graphql } 'react-apollo'; import type { operationcomponent, queryopts } 'react-apollo'; const hero_query = gql` query getcharacter($episode: episode!) { hero(episode: $episode) { name id friends { name id appearsin } } } `; type hero = { name: string, id: string, appearsin: string[], friends: hero[] }; type response = { hero: hero }; type props = { data: queryopts & response, } const withcharacter: operationcomponent<response, props> = graphql(hero_query, { options: () => ({ variables: { episode: 'jedi' }, }), }); class testclass extends react.component<props> { render() { const { loading, error, hero } = this.props.data; if (loading) return <div>loading</div>; if (error) return <h1>error</h1>; return <div>my hero: {hero.name}</div>; } } const testfn = ({ data: { loading, error, hero } }) => { if (loading) return <div>loading</div>; if (error) return <h1>error</h1>; return <div>my hero: {hero.name}</div>; }; export const clss = withcharacter(testclass); // error! export const fn = withcharacter(testfn); // works fine
here definition fr operationcomponent
type , it's core parts definition updates match 0.53 flow style:
export interface queryprops { error?: apolloerror, networkstatus: number, loading: boolean, variables: object, fetchmore: ( fetchmoreoptions: fetchmorequeryoptions & fetchmoreoptions, ) => promise<apolloqueryresult<any>>, refetch: (variables?: object) => promise<apolloqueryresult<any>>, startpolling: (pollinterval: number) => void, stoppolling: () => void, subscribetomore: (options: subscribetomoreoptions) => () => void, updatequery: ( mapfn: (previousqueryresult: any, options: updatequeryoptions) => any, ) => void, } export type mutationfunc<tresult> = ( opts: mutationopts, ) => promise<apolloqueryresult<tresult>>; export type childprops<p, r> = { data: queryprops & r, mutate: mutationfunc<r>, } & p; export interface operationcomponent< tresult: object = {}, townprops: object = {}, tmergedprops = childprops<townprops, tresult>, > { ( component: | statelesscomponent<tmergedprops> | class<react$component<any, tmergedprops, any>>, ): class<react$component<townprops, void>>, } declare export function graphql<tresult, tprops, tchildprops>( document: documentnode, operationoptions?: operationoption<tprops, tresult>, ): operationcomponent<tresult, tprops, tchildprops>;
when run flow focus-check src/test.js
(v. 0.53.1) get:
error: src/test.js:42 42: const { loading, error, hero } = this.props.data; ^^^^^^^ property `loading`. property cannot accessed on member of intersection type 42: const { loading, error, hero } = this.props.data; ^^^^^^^^^^^^^^^ intersection member 1: 31: data: queryopts & response, ^^^^^^^^^ queryopts error: 42: const { loading, error, hero } = this.props.data; ^^^^^^^ property `loading`. property not found in 31: data: queryopts & response, ^^^^^^^^^ queryopts member 2: 31: data: queryopts & response, ^^^^^^^^ response error: 42: const { loading, error, hero } = this.props.data; ^^^^^^^ property `loading`. property not found in 31: data: queryopts & response, ^^^^^^^^ object type error: src/test.js:42 42: const { loading, error, hero } = this.props.data; ^^^^^ property `error`. property cannot accessed on member of intersection type 42: const { loading, error, hero } = this.props.data; ^^^^^^^^^^^^^^^ intersection member 1: 31: data: queryopts & response, ^^^^^^^^^ queryopts error: 42: const { loading, error, hero } = this.props.data; ^^^^^ property `error`. property not found in 31: data: queryopts & response, ^^^^^^^^^ queryopts member 2: 31: data: queryopts & response, ^^^^^^^^ response error: 42: const { loading, error, hero } = this.props.data; ^^^^^ property `error`. property not found in 31: data: queryopts & response, ^^^^^^^^ object type error: src/test.js:55 55: export const clss = withcharacter(testclass); ^^^^^^^^^ class type: testclass. type incompatible v------------------------------- 123: | statelesscomponent<tmergedprops> 124: | class<react$component<any, tmergedprops, any>>, -----------------------------------------------^ union: type application of polymorphic type: type `statelesscomponent` | class type: type application of identifier `react$component`. see: node_modules/react-apollo/react-apollo.umd.js.flow:123 member 1: 123: | statelesscomponent<tmergedprops> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type application of polymorphic type: type `statelesscomponent`. see: node_modules/react-apollo/react-apollo.umd.js.flow:123 error: 123: | statelesscomponent<tmergedprops> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function type. callable signature not found in. see: node_modules/react-apollo/react-apollo.umd.js.flow:123 55: export const clss = withcharacter(testclass); ^^^^^^^^^ statics of testclass member 2: 124: | class<react$component<any, tmergedprops, any>>, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ class type: type application of identifier `react$component`. see: node_modules/react-apollo/react-apollo.umd.js.flow:124 error: 124: | class<react$component<any, tmergedprops, any>>, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type application of identifier `react$component`. many type arguments. expected @ 2. see: node_modules/react-apollo/react-apollo.umd.js.flow:124 29: declare class react$component<props, state = void> { ^^^^^^^^^^^^ see type parameters of definition here. see lib: /tmp/flow/flowlib_1135e841/react.js:29 found 3 errors
i've tried adding 0.53 improvements without avail:
export interface operationcomponent< tresult: object = {}, townprops: object = {}, tmergedprops = childprops<townprops, tresult>, > { ( component: react$componenttype<tmergedprops> ): react$componenttype<townprops>, }
oh... wrong query, should queryprops
, not queryopts
:
// @flow import * react 'react'; import gql 'graphql-tag'; import { graphql } 'react-apollo'; import type { operationcomponent, queryprops } 'react-apollo'; const hero_query = gql` query getcharacter($episode: episode!) { hero(episode: $episode) { name id friends { name id appearsin } } } `; type hero = { name: string, id: string, appearsin: string[], friends: hero[] }; type response = { hero: hero }; type props = { data: queryprops & response, mutate: any, } const withcharacter: operationcomponent<response, props> = graphql(hero_query, { options: () => ({ variables: { episode: 'jedi' }, }), }); class testclass extends react.component<props> { render() { const { loading, error, hero } = this.props.data; if (loading) return <div>loading</div>; if (error) return <h1>error</h1>; return <div>my hero: {hero.name}</div>; } } const testfn = ({ data: { loading, error, hero } }) => { if (loading) return <div>loading</div>; if (error) return <h1>error</h1>; return <div>my hero: {hero.name}</div>; }; export const clss = withcharacter(testclass); // works export const fn = withcharacter(testfn); // works
Comments
Post a Comment