Describe the bug
When useImplementingTypes is enabled and an interface has 2 or more implementing types, the generated mock code joins ternary expressions with || without wrapping each ternary in parentheses. Because || has higher precedence than ?: in JavaScript/TypeScript, the resulting expression is parsed incorrectly.
Generated (broken):
event: relationshipsToOmit.has('MeetingEvent') ? {} as MeetingEvent : mockMeetingEvent({}, relationshipsToOmit) || relationshipsToOmit.has('OtherEvent') ? {} as OtherEvent : mockOtherEvent({}, relationshipsToOmit)
JavaScript parses this as:
relationshipsToOmit.has('MeetingEvent')
? {} as MeetingEvent
: (mockMeetingEvent({}, relationshipsToOmit) || relationshipsToOmit.has('OtherEvent'))
? {} as OtherEvent
: mockOtherEvent({}, relationshipsToOmit)
Because mockMeetingEvent({}, relationshipsToOmit) returns a truthy object, the || short-circuits, and the second ternary's truthy branch ({} as OtherEvent) is always selected — meaning you always get an empty shell object instead of a real mock for the second (and subsequent) implementing types.
Expected (correct):
event: (relationshipsToOmit.has('MeetingEvent') ? {} as MeetingEvent : mockMeetingEvent({}, relationshipsToOmit)) || (relationshipsToOmit.has('OtherEvent') ? {} as OtherEvent : mockOtherEvent({}, relationshipsToOmit))
Your Example Website or App
No response
Steps to Reproduce the Bug or Issue
- Define a GraphQL schema with an interface that has 2+ implementing types
- Configure the plugin with
useImplementingTypes: true (the issue is worse with terminateCircularRelationships: true since the ternaries are more complex, but it affects both paths)
- Generate mocks
- Observe that fields typed as the interface always resolve to
{} as SecondType instead of a real mock
Minimal schema:
interface Event {
startDate: String
}
type MeetingEvent implements Event {
startDate: String
event: Event!
}
type OtherEvent implements Event {
startDate: String
somethingElse: String!
}
Expected behavior
Each implementing type's ternary expression should be wrapped in parentheses before being joined with ||, so that operator precedence is correct and each type's mock is independently evaluated.
Screenshots or Videos
No response
Platform
- OS: macOS
- NodeJS: 22.x
graphql-codegen-typescript-mock-data: latest (v3.x)
Codegen Config File
No response
Additional context
The fix is a one-line change in src/index.ts in the case 'implement': block — add .map((v) => '(' + v + ')') before .join(' || ').
Describe the bug
When
useImplementingTypesis enabled and an interface has 2 or more implementing types, the generated mock code joins ternary expressions with||without wrapping each ternary in parentheses. Because||has higher precedence than?:in JavaScript/TypeScript, the resulting expression is parsed incorrectly.Generated (broken):
JavaScript parses this as:
Because
mockMeetingEvent({}, relationshipsToOmit)returns a truthy object, the||short-circuits, and the second ternary's truthy branch ({} as OtherEvent) is always selected — meaning you always get an empty shell object instead of a real mock for the second (and subsequent) implementing types.Expected (correct):
Your Example Website or App
No response
Steps to Reproduce the Bug or Issue
useImplementingTypes: true(the issue is worse withterminateCircularRelationships: truesince the ternaries are more complex, but it affects both paths){} as SecondTypeinstead of a real mockMinimal schema:
Expected behavior
Each implementing type's ternary expression should be wrapped in parentheses before being joined with
||, so that operator precedence is correct and each type's mock is independently evaluated.Screenshots or Videos
No response
Platform
graphql-codegen-typescript-mock-data: latest (v3.x)Codegen Config File
No response
Additional context
The fix is a one-line change in
src/index.tsin thecase 'implement':block — add.map((v) => '(' + v + ')')before.join(' || ').