Skip to content

Commit 2e93338

Browse files
authored
fix: deduplicate interfaces implementing interfaces (#608)
1 parent 6e06f8f commit 2e93338

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

src/builder.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ export class SchemaBuilder {
10551055
const type = this.getInterface(i)
10561056
list.push(type, ...type.getInterfaces())
10571057
})
1058-
return list
1058+
return Array.from(new Set(list))
10591059
}
10601060

10611061
protected buildInterfaceFields(interfaces: (string | NexusInterfaceTypeDef<any>)[]) {

tests/__snapshots__/interfaceType.spec.ts.snap

+25
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,31 @@ Object {
2626

2727
exports[`interfaceType can not implement itself 1`] = `"GraphQL Nexus: Interface Node can't implement itself"`;
2828

29+
exports[`interfaceType deduplicates interfaces implementing interfaces 1`] = `
30+
"### This file was generated by Nexus Schema
31+
### Do not make changes to this file directly
32+
33+
34+
interface Node {
35+
id: ID
36+
}
37+
38+
interface Node2 implements Node {
39+
id: ID
40+
id2: ID
41+
}
42+
43+
type Foo implements Node2 & Node {
44+
id: ID
45+
id2: ID
46+
}
47+
48+
type Query {
49+
ok: Boolean!
50+
}
51+
"
52+
`;
53+
2954
exports[`interfaceType detects circular dependencies 1`] = `"GraphQL Nexus: Interface circular dependency detected NodeA -> NodeC -> NodeB -> NodeA"`;
3055

3156
exports[`interfaceType logs error when resolveType is not provided for an interface 1`] = `

tests/interfaceType.spec.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { graphql } from 'graphql'
22
import path from 'path'
3-
import { interfaceType, makeSchema, objectType, queryField } from '../src/core'
3+
import { interfaceType, makeSchema, objectType, queryField, generateSchema } from '../src/core'
44

55
describe('interfaceType', () => {
66
it('can be implemented by object types', async () => {
@@ -127,6 +127,38 @@ describe('interfaceType', () => {
127127
})
128128
).toThrowErrorMatchingSnapshot()
129129
})
130+
it('deduplicates interfaces implementing interfaces', async () => {
131+
const { schemaTypes } = await generateSchema.withArtifacts(
132+
{
133+
types: [
134+
interfaceType({
135+
name: 'Node',
136+
definition(t) {
137+
t.id('id')
138+
t.resolveType(() => null)
139+
},
140+
}),
141+
interfaceType({
142+
name: 'Node2',
143+
definition(t) {
144+
t.implements('Node')
145+
t.id('id2')
146+
t.resolveType(() => null)
147+
},
148+
}),
149+
objectType({
150+
name: 'Foo',
151+
definition(t) {
152+
t.implements('Node2', 'Node')
153+
},
154+
}),
155+
],
156+
outputs: false,
157+
},
158+
false
159+
)
160+
expect(schemaTypes).toMatchSnapshot()
161+
})
130162
it('detects circular dependencies', async () => {
131163
expect(() =>
132164
makeSchema({

0 commit comments

Comments
 (0)