import type { GraphQLCompositeType , GraphQLType } from '../type/definition' ; import { isAbstractType , isInterfaceType , isListType , isNonNullType , isObjectType , } from '../type/definition' ; import type { GraphQLSchema } from '../type/schema' ; /**
 * Provided two types, return true if the types are equal (invariant).
 */ export function isEqualType ( typeA , typeB ) { if ( typeA === typeB ) { return true ; } if ( isNonNullType ( typeA ) && isNonNullType ( typeB ) ) { return isEqualType ( typeA . ofType , typeB . ofType ) ; } if ( isListType ( typeA ) && isListType ( typeB ) ) { return isEqualType ( typeA . ofType , typeB . ofType ) ; } return false ; } /**
 * Provided a type and a super type, return true if the first type is either
 * equal or a subset of the second super type (covariant).
 */ export function isTypeSubTypeOf ( schema , maybeSubType , superType ) { if ( maybeSubType === superType ) { return true ; } if ( isNonNullType ( superType ) ) { if ( isNonNullType ( maybeSubType ) ) { return isTypeSubTypeOf ( schema , maybeSubType . ofType , superType . ofType ) ; } return false ; } if ( isNonNullType ( maybeSubType ) ) { return isTypeSubTypeOf ( schema , maybeSubType . ofType , superType ) ; } if ( isListType ( superType ) ) { if ( isListType ( maybeSubType ) ) { return isTypeSubTypeOf ( schema , maybeSubType . ofType , superType . ofType ) ; } return false ; } if ( isListType ( maybeSubType ) ) { return false ; } return ( isAbstractType ( superType ) && ( isInterfaceType ( maybeSubType ) || isObjectType ( maybeSubType ) ) && schema . isSubType ( superType , maybeSubType ) ) ; } /**
 * Provided two composite types, determine if they "overlap". Two composite
 * types overlap when the Sets of possible concrete types for each intersect.
 *
 * This is often used to determine if a fragment of a given type could possibly
 * be visited in a context of another type.
 *
 * This function is commutative.
 */ export function doTypesOverlap ( schema , typeA , typeB ) { if ( typeA === typeB ) { return true ; } if ( isAbstractType ( typeA ) ) { if ( isAbstractType ( typeB ) ) { return schema . getPossibleTypes ( typeA ) . some ( ( type ) => schema . isSubType ( typeB , type ) ) ; } return schema . isSubType ( typeA , typeB ) ; } if ( isAbstractType ( typeB ) ) { return schema . isSubType ( typeB , typeA ) ; } return false ; }