Skip to content

Commit e3c708a

Browse files
authored
Merge pull request #728 from APIs-guru/uniq_interfaces
Forbid object to declare that it implements same interface twice.
2 parents 5e17f83 + b460659 commit e3c708a

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 implementedTypeNames = {};
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+
!implementedTypeNames[iface.name],
462+
`${type.name} may declare it implements ${iface.name} only once.`
463+
);
464+
implementedTypeNames[iface.name] = true;
458465
if (typeof iface.resolveType !== 'function') {
459466
invariant(
460467
typeof type.isTypeOf === 'function',

0 commit comments

Comments
 (0)