diff --git a/src/type/__tests__/validation-test.ts b/src/type/__tests__/validation-test.ts index 7d215361f9..cd50be0425 100644 --- a/src/type/__tests__/validation-test.ts +++ b/src/type/__tests__/validation-test.ts @@ -2734,6 +2734,33 @@ describe('Interfaces must adhere to Interface they implement', () => { }, ]); }); + + it('rejects deprecated implementation field when interface field is not deprecated', () => { + const schema = buildSchema(` + interface Node { + id: ID! + } + + type Foo implements Node { + id: ID! @deprecated + } + + type Query { + foo: Foo + } + `); + + expectJSON(validateSchema(schema)).toDeepEqual([ + { + message: + 'Interface field Node.id is not deprecated, so implementation field Foo.id must not be deprecated.', + locations: [ + { line: 7, column: 17 }, + { line: 7, column: 13 }, + ], + }, + ]); + }); }); describe('assertValidSchema', () => { diff --git a/src/type/validate.ts b/src/type/validate.ts index deee23a372..8c29a9fe4f 100644 --- a/src/type/validate.ts +++ b/src/type/validate.ts @@ -433,6 +433,21 @@ function validateTypeImplementsInterface( ); } } + + // Asserts that field is not deprecated unless interface field is + if ( + ifaceField.deprecationReason == null && + typeField.deprecationReason != null + ) { + context.reportError( + `Interface field ${iface.name}.${fieldName} is not deprecated, so ` + + `implementation field ${type.name}.${fieldName} must not be deprecated.`, + [ + getDeprecatedDirectiveNode(typeField.astNode), + typeField.astNode?.type, + ], + ); + } } }