Nested Fragments Result in Type Errors With Fragment Types not Expanded in the Parent Query's Typing #9271
-
|
Most of the queries in my application are built up of fragments. In many cases these can be rather nested - a query that contains a fragment that's built up of a couple of other fragments, and so on. When using code-gen to generate a type for the parent query I'd expect that the generated type would also include the types for all of the child fragment but that doesn't seem to be true. Whenever I try to access a property that's part of a fragment off of the parent query, I get a TypeScript error that the property isn't found on the type. What am I doing wrong? This screenshot displays the query, fragment and the error (notice that it's on a property defined within the fragment) My config: A small repo that reproduces the issue: https://github.com/SimonPringleWallace/code-gen-issue/tree/main/src |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
What's causing that TypeScript error is, in fact, Fragment Masking, which is enabled by default with
That's why TypeScript believes You have two solutions here, either you embrace Fragment Masking (see Unleash the power of Fragments with GraphQL Codegen) or you disable Fragment Masking. Thank you for the repo, it was useful! I sent some pull requests to clarify the possible solutions here. PR 1: Initial SetupFirst pull request is to setup 🔗 Pull request: SimonPringleWallace/code-gen-issue#1 Solution 1: Embrace Fragment MaskingI highly recommend embracing fragment masking as I believe the data masking here is super important and will help you build better—and isolated—components. You can read more about fragment masking here: 📚 Unleash the power of Fragments with GraphQL Codegen. 🔗 Pull request: SimonPringleWallace/code-gen-issue#2 const CharactersCountFragment = graphql(`
fragment CharactersCount on Characters {
info {
count
}
}
`);
type CharactersCountProps = {
characters: FragmentType<typeof CharactersCountFragment>;
};
const CharactersCount = (props: CharactersCountProps) => {
const characters = useFragment(CharactersCountFragment, props.characters);
return <div>{characters?.info?.count}</div>;
};Solution 2: Disable Fragment MaskingIf you don't want to embrace fragment masking, we can disable them as described in the documentation: How to disable Fragment Masking. 🔗 Pull request: SimonPringleWallace/code-gen-issue#3 ...
generates: {
"src/common/graphql/types/": {
preset: "client",
+ presetConfig: {
+ fragmentMasking: false,
+ },
plugins: [],
},
},
... |
Beta Was this translation helpful? Give feedback.
-
|
Thank you @charpeni! So appreciate the detailed explanation and especially the PR with comments. Extremely helpful. Thanks for all your work on this tool - it's already been a complete game changer for our dev team. |
Beta Was this translation helpful? Give feedback.

What's causing that TypeScript error is, in fact, Fragment Masking, which is enabled by default with
client-preset.That's why TypeScript believes
infodoesn't exist on the type, because it is masked. If you want to pursue with fragment masking, the component will be responsible for expressing its data requirement by exposing a fragment that we'll be able to use in conjunction withuseFragmentto unmask the …