Graphql-code-generator: Generating react-apollo types for graphql import

Created on 13 Apr 2019  路  18Comments  路  Source: dotansimha/graphql-code-generator

Is it possible to generate types when you are using react-apollo as I am below. I do this to split out my component from the data source as a HOC.

```import { connect } from 'react-redux';
import { graphql, compose } from 'react-apollo';
import { get } from 'lodash-es';

import { Type, showToast } from 'components/Toast/Toast.dux';
import VALIDATE_CARD_MUTATION from './graphql/validateCardMutation.graphql';
import ValidateUserForm from './ValidateCardForm';

const validateUserMutation = graphql(VALIDATE_CARD_MUTATION, {
props: ({ ownProps, mutate }: { ownProps: { showToast: Function }; mutate?: any }) => ({
validateCard: (access: { access: { accessCode: number; id: string } }) =>
mutate({
variables: {
access,
},
})
.then((response: object) => response)
.catch((error: object) => {
ownProps.showToast(
Type.ERROR,
get(error, 'graphQLErrors[0].message', 'An error occurred while signing up for an account')
);
}),
}),
});

const withRedux = connect(
null,
(dispatch) => ({
showToast: (type: string, message: string) => dispatch(showToast(type, message)),
})
);

export default compose(
withRedux,
validateUserMutation
)(ValidateUserForm);```

enhancement plugins waiting-for-release

Most helpful comment

I figured out something for me.

typescript-schema.js in the root directory with

const { printSchema } = require('graphql');
const graphqlTag = require('graphql-tag');
var gql = graphqlTag.gql;

if (!gql) {
  // For some reason loading graphql-tag was inconsistent for me
  const apolloServerCore = require('apollo-server-core');
  gql = apolloServerCore.gql;
}

module.exports = {
  plugin: (schema) => {
    const printed = printSchema(schema);
    const typeDefs = gql(printed);
    if (typeDefs.loc) {
      delete typeDefs.loc;
    }
    return `
import { DocumentNode } from 'graphql';

const typeDefs = ${JSON.stringify(typeDefs, null, 2)} as DocumentNode;
export {
  typeDefs,
};
    `;
  }
}

and then in my codegen.yml

generates:
  src/generated/schema.ts:
      - "typescript-schema.js"

Now I can do

import { typeDefs } from './generated/schema'
// ...
const server = new ApolloServer({
  typeDefs,
  resolvers,
});

All 18 comments

Hi @chrisbrooks !
I'm not sure I'm getting the issue here, can you please elaborate?

If you wish to generate ready-to-use components from your .graphql file, you can do it with typescript-react-apollo plugin - you can choose between a Component, HOC or hooks. Then just use it directly instead of importing from a .graphql file.

@dotansimha I may be mistaken, but it sounds like @chrisbrooks is looking for codegen that uses the graphql wrapper from react-apollo rather than using the withMutation or withQuery helpers.

In my scenario, the addition of the graphql util would allow me to integrate codegen with LoonaJs, which extends the graphql HOC to offer more scalable mutation update support and local state solutions.

If I'm not mistaken the generic type configurations for graphql are similar to the other utils that are already implemented.

Thank you @TheCrow1213 .
@ardatan can you please take a look and see if we can support this use case? (Also, tagging @kamilkisiela for Loona)

@dotansimha I have tested it and noticed now I have something like ValidateUserFormMutationFn generated. Where that should be used as it is just a type?

For below one, if I use generated HoC wrapper function, I still see type problems.

const Component = withValidateUser({
  props: ({ mutate }) => ({
    validateCard: ({ resource }) => mutate({ variables: { resource } }),
  }),
});

Type Error

types.d.ts(68, 13): The expected type comes from the return type of this signature.

@veeramarni I think you can't use d.ts in this case, you need .ts (because it contains more than just declarations).

@dotansimha I was using generated .tsx and have this problem. It throws that none of the types matches.

Seems like I haven't copied full error. Here is the error.

        Type '{ validateCard: ({ resource }: { resource: any; }) => Promise<void | FetchResult<ValidateCardQuery, Record<string, any>, Record<string, any>>>; }' provides no match for the signature '(options?: MutationOptions<RemoveChangedEventMutation, ValidateCardMutationVariables>): Promise<void | FetchResult<ValidateCardMutation, Record<string, any>, Record<string, any>>>'.ts(2322)

types.d.ts(68, 13): The expected type comes from the return type of this signature.

@veeramarni If you are using .tsx extension for your generated file, so I'm not getting why you had errors from types.d.ts file?
Please share your codegen.yml config file, and you schema and queries (if possible, in a repository with a reproduction)

@veeramarni that's exactly what typescript-react-apollo does, it generates HOC (or Component, or Hooks) for usage with React, and it comes with a built-in typings (use withComponent: false, withHooks: false, withHOC: true config to get that).

You can use near-operation-file preset (see website for docs) in order to generate a file per each operation.

@dotansimha I have tried with withHOC: true but it only generates withApollo(component) but not with graphql() function. graphql() functions gives additional feature support which withApollo doesn't provide.

I am interested in a plugin that generates typeDefs, which are DocumentNode or DocumentNode[] of schemas for use with Apollo servers, be it lambda, express, or others.

So far all I can find is generating DocumentNodes for client frameworks, such as react, angular, and stencil.

import { ApolloServer } from 'apollo-server-lambda';
import resolvers from './my-code/resolvers'
// vvvv
import typeDefs from './generated/typeDefs';
// ^^^^

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

export const graphqlHandler = server.createHandler({
  cors: {
    origin: '*',
    credentials: true,
  },
});

@LeviSchuck You can use graphql-import-node
https://github.com/ardatan/graphql-import-node

@ardatan I was hoping something closer to compile time like what this project offers

@dotansimha Can you confirm whether graphql() function is implemented as I can see them generated?

I figured out something for me.

typescript-schema.js in the root directory with

const { printSchema } = require('graphql');
const graphqlTag = require('graphql-tag');
var gql = graphqlTag.gql;

if (!gql) {
  // For some reason loading graphql-tag was inconsistent for me
  const apolloServerCore = require('apollo-server-core');
  gql = apolloServerCore.gql;
}

module.exports = {
  plugin: (schema) => {
    const printed = printSchema(schema);
    const typeDefs = gql(printed);
    if (typeDefs.loc) {
      delete typeDefs.loc;
    }
    return `
import { DocumentNode } from 'graphql';

const typeDefs = ${JSON.stringify(typeDefs, null, 2)} as DocumentNode;
export {
  typeDefs,
};
    `;
  }
}

and then in my codegen.yml

generates:
  src/generated/schema.ts:
      - "typescript-schema.js"

Now I can do

import { typeDefs } from './generated/schema'
// ...
const server = new ApolloServer({
  typeDefs,
  resolvers,
});

Fixed in 1.4.0 馃帀

Was this page helpful?
0 / 5 - 0 ratings