apollographql / apollographql/apollo-tooling
Respect and use fragment boundaries when generating types to avoid explosion
- Dominant language
- TypeScript
- Stars
- 3k
- Forks
- 460
- PR merge metrics
- No merged PRs in 30d
Description
Please excuse me if this has been suggested before, or if this feature already exists. I couldn't find anything but perhaps I didn't search on the right keywords. This feature request is partly a bug because currently the generated output is so large that is unusable. I have a query with some nested fragments. The resulting type files are several megabytes large (100k+ lines). So large that `tsc` gives up on trying to parse it.
It's perhaps worth noting that, although the query is quite deep and (fully expanded) quite large, it is not a particularly difficult query to satisfy.
I've looked at the `mergeInFieldsFromFragmentSpreads` CLI option but (aside from the CLI option being broken) it removes properties defined in fragments, which is equally not useful.
Suppose you have this query:
```gql
query MyQuery {
foo {
...MyFragment
}
}
fragment MyFragment on foo {
bar
}
```
Then the resullt of `apollo client:codegen --target=typescript` is two type files:
**MyQuery.ts**
```typescript
export interface MyQuery_foo {
bar: string;
}
export interface MyQuery {
foo: MyQuery_foo;
}
```
**MyFragment.ts**
```typescript
export interface MyFragment {
bar: string;
}
```
Instead, it would greatly benefit me if the fragment type is linked into the query type:
**MyQuery.ts**
```typescript
export interface MyQuery {
foo: MyFragment; // import from MyFragment.ts or MyFragment is redeclared locally
}
```
**MyFragment.ts**
```typescript
export interface MyFragment {
bar: string;
}
```
It is key that the fragment types are re-used exactly as they appear in the query to avoid exploding the types.
Having re-used fragment types also makes using the types easier. One downside is that these types are more vulnerable to breakage if you rearrange the fragments but that is a tradeoff I am very willing to make.
This output is breaking so I would expect that you can choose to enable this behavior through a feature flag although I certainly wouldn't mind if this becomes the default behavior.
Contributor guide
Research direction
Start with the TypeScript target and the mergeInFieldsFromFragmentSpreads CLI option mentioned in the issue. Compare the current generated MyQuery and MyFragment examples with the proposed fragment-linked output; done means nested fragment types are reused without producing unusably large files, with the behavior controlled by a feature flag.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, typescript
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100