# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tutorial.specian.co.uk/frontend/types-generation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
