dotansimha / dotansimha/graphql-code-generator

Typeerror occurs when trying to pass whole fragment array to another FragmentType<>[] prop

Open
#9,975 0 comments 2 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
11.3k
Forks
1.4k
Avg merge
1d 1h
Merged PRs (30d)
23

Description

### Which packages are impacted by your issue?

@graphql-codegen/client-preset

### Describe the bug

When there are a fragment embedded in another framgnet to same object, trying to pass whole array of fragment that returned from useFragment to another FragmentType<>[] prop, type error occors.

```ts
export const FilmContainerFragment = graphql(/* GraphQL */ `
fragment FilmContainer on Film {
id
title
...FilmDetails
}
`)

const FilmList = (props: {
film: FragmentType[]
}) => {
const film = useFragment(FilmContainerFragment, props.film)

console.log(film[0].title)

// The type 'readonly FilmContainerFragment[]' is 'readonly' and cannot be assigned to the mutable type '{ ' $fragmentRefs'?: { FilmDetailsFragment: FilmDetailsFragment; }; }[]'.(4104)
// App.tsx(33, 3): The expected type comes from property 'film' which is declared here on type '{ film: { ' $fragmentRefs'?: { FilmDetailsFragment: FilmDetailsFragment; }; }[]; }'
FilmDetails({ film: film })

// FilmContainerFragment[] itself is completely satisfied the type FragmentType[]
// but useFragment() adds extra 'readonly []' breaks the satisfaction
const assert1: FilmContainerFragmentType[] extends FragmentType<
typeof FilmDetailsFragment
>[]
? true
: false = true

const assert2: readonly FilmContainerFragmentType[] extends FragmentType<
typeof FilmDetailsFragment
>[]
? true
: false = false

// FilmContainerFragment[] can expanded to
// ( { __typename?: 'Film', id: string, title?: string | null }
// & { ' $fragmentRefs'?: { 'FilmDetailsFragment': FilmDetailsFragment } }
// ) & { ' $fragmentName'?: 'FilmContainerFragment' }[]

// FragmentType[] can expanded to
// { ' $fragmentRefs'?: { 'FilmDetailsFragment': FilmDetailsFragment } }[]
}

export const FilmDetailsFragment = graphql(/* GraphQL */ `
fragment FilmDetails on Film {
id
title
releaseDate
producers
}
`)

const FilmDetails = (props: {
film: FragmentType[]

// Add `readonly` before FragmneType<> can be workaround here
// film: readonly FragmentType[]
}) => {
const film = useFragment(FilmDetailsFragment, props.film)
}
```

### Your Example Website or App

https://stackblitz.com/edit/github-qjbrdu?file=App.ts,codegen.ts,package.json

### Steps to Reproduce the Bug or Issue

1. Open stackblitz above
2. Open App.ts file
3. See how type errors occors

### Expected behavior

It can pass whole fragment array to another component's FragmentType<> prop without type errors.

### Screenshots or Videos

_No response_

### Platform

- OS: Linux
- NodeJS: v18.18.0
- `graphql` version: 16.2.0
- `@graphql-codegen/*` version(s): 4.2.5

### Codegen Config File

```
import { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
schema: 'https://swapi-graphql.netlify.app/.netlify/functions/index',
documents: ['src/**/*.tsx'],
ignoreNoDocuments: true, // for better experience with the watcher
generates: {
'./src/gql/': {
preset: 'client',
},
},
};

export default config;
```

### Additional context

_No response_

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.