> For the complete documentation index, see [llms.txt](https://tutorial.specian.co.uk/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tutorial.specian.co.uk/frontend/types-generation.md).

# Types generation

Types are only enforced between the backend and frontend with GraphQL at runtime (when sending the request). What happens if we change something in the backend and forget to reflect this change in the frontend? It will crash. Let's make sure this doesn't happen.

We are going to generate types from the GraphQL schema with [Apollo CLI](https://github.com/apollographql/apollo-tooling). Then use them on the frontend. If something changes on the backend, Typescript will let us know.

{% code title="\~/" %}

```
yarn add apollo
```

{% endcode %}

Start the server:

{% code title="\~/packages/api" %}

```
$ ts-node -T src/index.ts
```

{% endcode %}

Create a new package:

{% code title="\~/" %}

```
mkdir packages/types
```

{% endcode %}

Generate the types:

{% code title="\~/packages" %}

```
apollo codegen:generate --target=typescript --queries='packages/web/src/**/*.tsx' --endpoint=http://localhost:8080/graphql --tagName=gql --outputFlat packages/types/graphql.d.ts
```

{% endcode %}

To fix `Apollo does not support anonymous operations` change:

{% code title="LinksPage.tsx" %}

```typescript
const { data, loading, error } = useQuery(gql`
    {
      health {
        ok
      }
    }
  `);
```

{% endcode %}

to

{% code title="LinksPage.tsx" %}

```typescript
const { data, loading, error } = useQuery(gql`
    query health {
      health {
        ok
      }
    }
  `);
```

{% endcode %}

You should now see `types.d.ts` in `packages/types`. Let's create a `package.json` and `index.d.ts` for this package:

{% tabs %}
{% tab title="\~/packages/types/package.json" %}

```typescript
{
  "name": "api-types",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {},
  "devDependencies": {}
}

```

{% endtab %}

{% tab title="index.d.ts" %}

```typescript
export * from './graphql'
```

{% endtab %}
{% endtabs %}

and now use Lerna to add the `types` to `web`:

```
$ lerna add api-types --scope=web
```

We can now import the variables:

```typescript
import {
  signUp as SignUpResponse,
  signUpVariables as SignUpVariables
} from "api-types";
```

and enforce types with queries and mutations:

```typescript
const [signUpMutation, { loading, error }] = useMutation<
    SignUpResponse,
    SignUpVariables
  >(SIGNUP_MUTATION, {
    onCompleted({ signUp }) {
      // ...
    }
  });
```

{% hint style="warning" %}
`yarn add <dependency>` won't work in anymore. Use `lerna add dependency> --scope=web` instead.
{% endhint %}

Later, if we have a React Native app or a queue worker, we will be able to reuse the types from this package.

{% hint style="info" %}
[`types-generation`](https://github.com/florianherrengt/book-code/tree/types-generation) branch and [pull request](https://github.com/florianherrengt/book-code/pull/5/files) available on GitHub.
{% endhint %}
