Skip to content

Commit 8234f4e

Browse files
committed
Forbid object to declare that it implements same interface twice.
For details please see this PR: graphql/graphql-spec#262
1 parent bacd412 commit 8234f4e

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

src/type/__tests__/validation-test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,30 @@ describe('Type System: Object interfaces must be array', () => {
559559
);
560560
});
561561

562+
it('rejects an Object that declare it implements same interface more than once', () => {
563+
expect(() => {
564+
const NonUniqInterface = new GraphQLInterfaceType({
565+
name: 'NonUniqInterface',
566+
resolveType: () => null,
567+
fields: { f: { type: GraphQLString } },
568+
});
569+
570+
const AnotherInterface = new GraphQLInterfaceType({
571+
name: 'AnotherInterface',
572+
resolveType: () => null,
573+
fields: { f: { type: GraphQLString } },
574+
});
575+
576+
schemaWithFieldType(new GraphQLObjectType({
577+
name: 'SomeObject',
578+
interfaces: () => [ NonUniqInterface, AnotherInterface, NonUniqInterface ],
579+
fields: { f: { type: GraphQLString } }
580+
}));
581+
}).to.throw(
582+
'SomeObject may declare it implements NonUniqInterface only once.'
583+
);
584+
});
585+
562586
it('rejects an Object type with interfaces as a function returning an incorrect type', () => {
563587
expect(
564588
() => schemaWithFieldType(new GraphQLObjectType({

src/type/definition.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,12 +449,19 @@ function defineInterfaces(
449449
`${type.name} interfaces must be an Array or a function which returns ` +
450450
'an Array.'
451451
);
452+
453+
const seenInterfaceNames = [];
452454
interfaces.forEach(iface => {
453455
invariant(
454456
iface instanceof GraphQLInterfaceType,
455457
`${type.name} may only implement Interface types, it cannot ` +
456458
`implement: ${String(iface)}.`
457459
);
460+
invariant(
461+
seenInterfaceNames.indexOf(iface.name) === -1,
462+
`${type.name} may declare it implements ${iface.name} only once.`
463+
);
464+
seenInterfaceNames.push(iface.name);
458465
if (typeof iface.resolveType !== 'function') {
459466
invariant(
460467
typeof type.isTypeOf === 'function',

0 commit comments

Comments
 (0)