@@ -21,6 +21,8 @@ import {
21
21
GraphQLEnumType ,
22
22
GraphQLList ,
23
23
GraphQLNonNull ,
24
+ GraphQLInterfaceType ,
25
+ GraphQLUnionType ,
24
26
isAbstractType
25
27
} from '../type/definition' ;
26
28
import type {
@@ -637,6 +639,9 @@ function completeValueCatchingError(
637
639
* value of the type by calling the `serialize` method of GraphQL type
638
640
* definition.
639
641
*
642
+ * If the field is an abstract type, determine the runtime type of the value
643
+ * and then complete based on that type
644
+ *
640
645
* Otherwise, the field type expects a sub-selection set, and will complete the
641
646
* value by evaluating all sub-selections.
642
647
*/
@@ -715,32 +720,19 @@ function completeValue(
715
720
) ;
716
721
}
717
722
718
- // Field type must be Object, Interface or Union and expect sub-selections.
719
- let runtimeType: ?GraphQLObjectType;
720
-
721
- if (isAbstractType(returnType)) {
722
- const abstractType = ( ( returnType : any ) : GraphQLAbstractType ) ;
723
- runtimeType = abstractType . getObjectType ( result , info ) ;
724
- if ( runtimeType && ! abstractType . isPossibleType ( runtimeType ) ) {
725
- throw new GraphQLError (
726
- `Runtime Object type "${ runtimeType } " is not a possible type ` +
727
- `for "${ abstractType } ".` ,
728
- fieldASTs
729
- ) ;
730
- }
731
- }
732
-
733
- if (!runtimeType) {
734
- return null ;
723
+ if (returnType instanceof GraphQLInterfaceType ||
724
+ returnType instanceof GraphQLUnionType) {
725
+ return completeAbstractValue (
726
+ exeContext ,
727
+ returnType ,
728
+ fieldASTs ,
729
+ info ,
730
+ result
731
+ ) ;
735
732
}
736
733
737
- return completeObjectValue(
738
- exeContext,
739
- runtimeType,
740
- fieldASTs,
741
- info,
742
- result
743
- );
734
+ // Not reachable
735
+ return null;
744
736
}
745
737
746
738
/**
@@ -831,6 +823,40 @@ function completeObjectValue(
831
823
return executeFields ( exeContext , returnType , result , subFieldASTs ) ;
832
824
}
833
825
826
+ /**
827
+ * Complete an value of an abstract type by determining the runtime type of
828
+ * that value, then completing based on that type.
829
+ */
830
+ function completeAbstractValue (
831
+ exeContext : ExecutionContext ,
832
+ returnType : GraphQLAbstractType ,
833
+ fieldASTs : Array < Field > ,
834
+ info: GraphQLResolveInfo,
835
+ result: mixed
836
+ ): mixed {
837
+ const abstractType = ( ( returnType : any ) : GraphQLAbstractType ) ;
838
+ const runtimeType = abstractType . getObjectType ( result , info ) ;
839
+ if ( runtimeType && ! abstractType . isPossibleType ( runtimeType ) ) {
840
+ throw new GraphQLError (
841
+ `Runtime Object type "${ runtimeType } " is not a possible type ` +
842
+ `for "${ abstractType } ".` ,
843
+ fieldASTs
844
+ ) ;
845
+ }
846
+
847
+ if ( ! runtimeType ) {
848
+ return null ;
849
+ }
850
+
851
+ return completeObjectValue (
852
+ exeContext ,
853
+ runtimeType ,
854
+ fieldASTs ,
855
+ info ,
856
+ result
857
+ ) ;
858
+ }
859
+
834
860
/**
835
861
* If a resolve function is not given, then a default resolve behavior is used
836
862
* which takes the property of the source object of the same name as the field
0 commit comments