@@ -23,8 +23,8 @@ import * as debugFactory from "debug";
2323type mixed = Record < string , any > | string | number | boolean | undefined | null ;
2424
2525export interface FieldsByTypeName {
26- [ str : string ] : {
27- [ str : string ] : ResolveTree ;
26+ [ typeName : string ] : {
27+ [ fieldName : string ] : ResolveTree ;
2828 } ;
2929}
3030
@@ -350,17 +350,28 @@ function getType(
350350export function simplifyParsedResolveInfoFragmentWithType (
351351 parsedResolveInfoFragment : ResolveTree ,
352352 type : GraphQLType
353- ) {
353+ ) : ResolveTree & { fields : { [ fieldName : string ] : ResolveTree } } {
354354 const { fieldsByTypeName } = parsedResolveInfoFragment ;
355- const fields = { } ;
355+ const fields : { [ fieldName : string ] : ResolveTree } = Object . create ( null ) ;
356356 const strippedType = getNamedType ( type ) ;
357357 if ( isCompositeType ( strippedType ) ) {
358358 Object . assign ( fields , fieldsByTypeName [ strippedType . name ] ) ;
359359 if ( strippedType instanceof GraphQLObjectType ) {
360360 const objectType : GraphQLObjectType = strippedType ;
361- // GraphQL ensures that the subfields cannot clash, so it's safe to simply overwrite them
361+ // GraphQL ensures that the subfields cannot clash, so it's safe to simply merge them
362362 for ( const anInterface of objectType . getInterfaces ( ) ) {
363- Object . assign ( fields , fieldsByTypeName [ anInterface . name ] ) ;
363+ const interfaceFields = fieldsByTypeName [ anInterface . name ] ;
364+ for ( const fieldName of Object . keys ( interfaceFields ) ) {
365+ const interfaceField = interfaceFields [ fieldName ] ;
366+ if ( fields [ fieldName ] ) {
367+ fields [ fieldName ] = recursiveMerge (
368+ fields [ fieldName ] ,
369+ interfaceField
370+ ) ;
371+ } else {
372+ fields [ fieldName ] = interfaceField ;
373+ }
374+ }
364375 }
365376 }
366377 }
@@ -370,6 +381,35 @@ export function simplifyParsedResolveInfoFragmentWithType(
370381 } ;
371382}
372383
384+ function recursiveMerge ( treeA : ResolveTree , treeB : ResolveTree ) : ResolveTree {
385+ const result : ResolveTree = {
386+ ...treeA ,
387+ fieldsByTypeName : Object . create ( null ) ,
388+ } ;
389+
390+ for ( const tree of [ treeA , treeB ] ) {
391+ for ( const typeName of Object . keys ( tree . fieldsByTypeName ) ) {
392+ if ( ! result . fieldsByTypeName [ typeName ] ) {
393+ result . fieldsByTypeName [ typeName ] = Object . create ( null ) ;
394+ }
395+ const targetFields = result . fieldsByTypeName [ typeName ] ;
396+ const sourceFields = tree . fieldsByTypeName [ typeName ] ;
397+ for ( const fieldName of Object . keys ( sourceFields ) ) {
398+ if ( ! targetFields [ fieldName ] ) {
399+ targetFields [ fieldName ] = sourceFields [ fieldName ] ;
400+ } else {
401+ targetFields [ fieldName ] = recursiveMerge (
402+ targetFields [ fieldName ] ,
403+ sourceFields [ typeName ]
404+ ) ;
405+ }
406+ }
407+ }
408+ }
409+
410+ return result ;
411+ }
412+
373413export const parse = parseResolveInfo ;
374414export const simplify = simplifyParsedResolveInfoFragmentWithType ;
375415export const getAlias = getAliasFromResolveInfo ;
0 commit comments