These TypeScript errors appear in almost every React project, yet they keep catching developers off guard. Here are the patterns that cause the most frustration and how to handle them properly.

1. Variable type inference problems
TypeScript can't always guess what type your variable should be, especially with empty arrays or objects.
You writelet items = [];
thinking it's obvious what goes inside, but TypeScript seesany[]
and throws errors when you try to use array methods later.
The fix:
- Explicitly type your variables:
let items: Product[] = [];
- Use
typeof
for existing data:let filteredPosts: typeof data.allPosts = [];
- Let TypeScript infer when possible:
const items = data.products;
(already typed)
2. Fragment type access with GraphQL
GraphQL Code Generator uses fragment masking, preventing direct property access on fragment-typed data.
The error: Property 'id' does not exist on type FragmentType<PostFragment>
What's happening: Fragment masking enforces type safety by hiding properties until you explicitly extract them.
The solution:
- Import both the fragment type AND the FragmentDoc
- Use
getFragmentData(PostFragmentDoc, post)
to extract data - Access properties from extracted data, not the original fragment
3. Optional chaining oversights
Accessing nested properties without checking if parent objects exist first causes runtime crashes.
data.user.profile.avatar.url
works in development with test data, but crashes in production whenprofile
doesn't exist.
Safe patterns:
- Use optional chaining:
data.user?.profile?.avatar?.url
- Type guards:
if (data.user?.profile) { /* safe to access profile properties */ }
- Nullish coalescing:
data.user?.name ?? 'Anonymous'
4. Union type assumptions
When TypeScript knows a value could be multiple types, you can't assume which one it is.
The mistake: if (record.__typename === 'QuoteBlock')
won't work with fragments because __typename
isn't available.
Proper type narrowing:
- Check for actual properties:
if ('quote' in record && 'author' in record)
- Use discriminated unions with literal types
- Create type guard functions for complex checks
5. Missing field assertions
Using fields that might not exist yet in your GraphQL schema or CMS.
Instead of @ts-ignore
(which hides real problems), handle it properly:
Temporary fields:
- Make fields optional in your types:
relatedPosts?: Post[]
- Use optional chaining when accessing:
post.relatedPosts?.length
- Add GraphQL directives:
relatedPosts @include(if: true)
Common debugging steps
When you hit a TypeScript error:
- Read the full error message - TypeScript errors are verbose but informative
- Check if you need
getFragmentData
for fragments - Look for missing optional chaining on nested properties
- Verify you've run
npm run generate-ts-types
after GraphQL changes - Use type guards instead of type assertions when possible