@@ -235,16 +235,28 @@ func typeMapReducer(typeMap: TypeMap, type: GraphQLType) throws -> TypeMap {
235235 return typeMap // Should never happen
236236 }
237237
238- guard typeMap [ type. name] == nil || typeMap [ type. name] is GraphQLTypeReference else {
239- guard typeMap [ type. name] ! == type || type is GraphQLTypeReference else {
240- throw GraphQLError (
241- message:
242- " Schema must contain unique named types but contains multiple " +
243- " types named \" \( type. name) \" . "
244- )
238+ if let existingType = typeMap [ type. name] {
239+ if existingType is GraphQLTypeReference {
240+ if type is GraphQLTypeReference {
241+ // Just short circuit because they're both type references
242+ return typeMap
243+ }
244+ // Otherwise, fall through and override the type reference
245+ } else {
246+ if type is GraphQLTypeReference {
247+ // Just ignore the reference and keep the concrete one
248+ return typeMap
249+ } else if !( existingType == type) {
250+ throw GraphQLError (
251+ message:
252+ " Schema must contain unique named types but contains multiple " +
253+ " types named \" \( type. name) \" . "
254+ )
255+ } else {
256+ // Otherwise, it's already been defined so short circuit
257+ return typeMap
258+ }
245259 }
246-
247- return typeMap
248260 }
249261
250262 typeMap [ type. name] = type
@@ -363,6 +375,15 @@ func replaceTypeReferences(typeMap: TypeMap) throws {
363375 try typeReferenceContainer. replaceTypeReferences ( typeMap: typeMap)
364376 }
365377 }
378+
379+ // Check that no type names map to TypeReferences. That is, they have all been resolved to actual types.
380+ for (typeName, graphQLNamedType) in typeMap {
381+ if graphQLNamedType is GraphQLTypeReference {
382+ throw GraphQLError (
383+ message: " Type \" \( typeName) \" was referenced but not defined. "
384+ )
385+ }
386+ }
366387}
367388
368389func resolveTypeReference( type: GraphQLType , typeMap: TypeMap ) throws -> GraphQLType {
0 commit comments