Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relay 13: understanding the new Flow types #3717

Open
mrtnzlml opened this issue Jan 5, 2022 · 5 comments
Open

Relay 13: understanding the new Flow types #3717

mrtnzlml opened this issue Jan 5, 2022 · 5 comments

Comments

@mrtnzlml
Copy link
Contributor

mrtnzlml commented Jan 5, 2022

Hello! 👋 First and foremost, thanks for investing your energy into bringing the new Rust Compiler into OSS world as well. 👍

I have some questions regarding the new compiler and specifically regarding the new Flow types and how to use them. Could you please have a look and share with me if I am using it correctly or not? I feel like I am missing something important because the GraphQL tags are now annotated in the generated file precisely (which is awesome but I am not sure how to use it correctly). 🤔

useFragment

flowTypegen: {
  phase: 'Final',
}

Before:

import type { ProductCreateFormData$key } from "./__generated__/ProductCreateFormData.graphql";

const data = useFragment<ProductCreateFormData$key>(graphql` … `);

After:

import type {
  ProductCreateFormData$data,
  ProductCreateFormData$fragmentType,
  ProductCreateFormData$key, // used for prop annotation
} from './__generated__/ProductCreateFormData.graphql';

const data = useFragment<ProductCreateFormData$fragmentType, ProductCreateFormData$data>(graphql` … `);

Concern: the *.graphql.js file already exports the fragment with the fragment type. Should users use it somehow?

module.exports = ((node/*: any*/)/*: Fragment<
  ProductCreateFormData$fragmentType,
  ProductCreateFormData$data,
>*/);

useMutation

Basically no change but only with:

flowTypegen: {
  phase: 'Compat',
}

However, with phase: 'Final' there is no *Mutation type and the only exported types are *$variables and *$data. How should the "Final" phase be used together with useMutation?

Similarly, usePreloadedQuery also doesn't generate *Query type in the "Final" phase that was previously used like this:

usePreloadedQuery<ProductsGridModalBodyQuery>(graphql` … `);

🤔

useLazyLoadQuery

Before:

import type { NavigationHeaderBadgeQuery } from "./__generated__/NavigationHeaderBadgeQuery.graphql";

const data = useLazyLoadQuery<NavigationHeaderBadgeQuery>(graphql` … `);

After:

import type {
  NavigationHeaderBadgeQuery$data,
  NavigationHeaderBadgeQuery$variables,
} from './__generated__/NavigationHeaderBadgeQuery.graphql';

const data = useLazyLoadQuery
  NavigationHeaderBadgeQuery$variables,
  NavigationHeaderBadgeQuery$data,
>(graphql` … `);

Is this the correct way how to use the new types?

Thank you very much for having a look! 😎

@mrtnzlml
Copy link
Contributor Author

mrtnzlml commented Jan 5, 2022

WOW! I just discovered that these new Flow types are directly supported by Flow! 🤯

So it seems like the expected way how to use Relay with Flow is to set the following in .flowconfig:

relay_integration=true
relay_integration.module_prefix=./__generated__/
relay_integration.excludes=.*/__tests__/.*
relay_integration.excludes=.*/__flowtests__/.*

and basically, remove all manual generic types, so for example before:

const data = useLazyLoadQuery<NavigationHeaderBadgeQuery>(graphql` … `);

and after:

const data = useLazyLoadQuery(graphql` … `);

Which still type checks all the fields and everything correctly. Is this the idea? Well done! 😃

@alunyov
Copy link
Contributor

alunyov commented Jan 6, 2022

Is this the idea?

Yes, this is the main idea. We'll be updating the docs with instructions on how to use the new types.

cc @kassens

@RichardLindhout
Copy link

Will this be possible in Typescript too?

@josephsavona
Copy link
Contributor

@RichardLindhout As far as we know the automatic understanding of GraphQL tags isn't possible in TypeScript. We worked directly with the Flow team to teach Flow how to understand GraphQL tags and the way Relay compiler (and the Babel plugin) cooperate to turn them into require calls. The translation is very straightforward (fragment Foo ... turns into a require('Foo.graphql')) but this does require explicit support from the type checker.

It would be amazing to see TypeScript support this, though!

@RichardLindhout
Copy link

@DanielRosenwasser is something like this possible in Typescript or is it possible with a plugin or something like that?

mrtnzlml referenced this issue Jun 10, 2022
Reviewed By: gkz

Differential Revision: D33104427

fbshipit-source-id: 151d48ea02f71e956e9d742e455719e847fc9160
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants
@alunyov @mrtnzlml @josephsavona @RichardLindhout and others