Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to type an exported RelayContainer

I'm trying to type (with flowtype) the components I'm enhancing with Relay.createContainer.

I looked into the types exported by the "react-relay" package but ReactContainer doesn't seem to carry over Props.

I experimented with RelayContainer, ReactClass, React$Component etc, in the end the closest thing to the expected result I could get is :

// Foo.js // @flow import React from "react"; import Relay from "react-relay";  type Props = { title: string; } const Foo({ title }: Props) => (<div>{title}</div>);  const exported: Class<React$Component<void, Props, void>> = Relay.createContainer(Foo, {   fragments: { ... } });  export default exported; 

--

// Bar.js // @flow  import React from "react"; import Foo from "./Foo.js"; const Bar = () => <Foo />;  

Now flow will complain in Foo.js around Props that Bar doesn't provide the title prop, which kinda what I want (I'd like it to complain in Bar.js but it's a detail). However if Bar was also a RelayContainer referencing Foo's fragment flow would complain that it can't find getFragment in Foo's properties:

// Bar.js // @flow  import React from "react"; import Relay from "react-relay"; import Foo from "./Foo.js";  const Bar = () => <Foo />;   export default Relay.createContainer(Bar, {   fragments: {     baz: () => Relay.QL`       fragment on Baz {         ${Foo.getFragment("foo")}       }     `   } } 

In the end I'm trying to type the output of Relay.createContainer so that it carries over the typing of the decorated component. I looked into the Relay's internal types and saw https://github.com/facebook/relay/blob/8567b2732d94d75f0eacdce4cc43c3606960a1d9/src/query/RelayFragmentReference.js#L211 but I feel like it's not the way to go to add in Relay's properties.

Any idea how could I achieve this ?

like image 902
chollier Avatar asked Sep 06 '16 22:09

chollier


1 Answers

as @gre pointed out, now the Relay Compiler generates Flow types for the fragment and these are exported in generated files within a __generated__ subdirectory.

generating said file by running the Relay Compiler

relay-compiler --src ./src --schema ./schema.json

You would then import the flow types for the field props like so:

import type { MyComponent_myField } from "./__generated__/MyComponent_myField.graphql"; class MyComponent extends Component<{   myField: MyComponent_myField, }> {   render() {     return <div>Example</div>;   } } export default createFragmentContainer(MyComponent, {   myField: graphql`     fragment MyComponent_myField on MyType {        edges {           node {             _id             foo           }        }     }   ` }); 

Although AFAIK currently types for spreaded fragments are not generated unless you use the Haste module system

like image 65
Alfonso Embid-Desmet Avatar answered Sep 20 '22 16:09

Alfonso Embid-Desmet