UNPKG

3.27 kBJavaScriptView Raw
1import {
2 isAbstractType,
3 isInterfaceType,
4 isListType,
5 isNonNullType,
6 isObjectType,
7} from '../type/definition.mjs';
8
9/**
10 * Provided two types, return true if the types are equal (invariant).
11 */
12export function isEqualType(typeA, typeB) {
13 // Equivalent types are equal.
14 if (typeA === typeB) {
15 return true;
16 } // If either type is non-null, the other must also be non-null.
17
18 if (isNonNullType(typeA) && isNonNullType(typeB)) {
19 return isEqualType(typeA.ofType, typeB.ofType);
20 } // If either type is a list, the other must also be a list.
21
22 if (isListType(typeA) && isListType(typeB)) {
23 return isEqualType(typeA.ofType, typeB.ofType);
24 } // Otherwise the types are not equal.
25
26 return false;
27}
28/**
29 * Provided a type and a super type, return true if the first type is either
30 * equal or a subset of the second super type (covariant).
31 */
32
33export function isTypeSubTypeOf(schema, maybeSubType, superType) {
34 // Equivalent type is a valid subtype
35 if (maybeSubType === superType) {
36 return true;
37 } // If superType is non-null, maybeSubType must also be non-null.
38
39 if (isNonNullType(superType)) {
40 if (isNonNullType(maybeSubType)) {
41 return isTypeSubTypeOf(schema, maybeSubType.ofType, superType.ofType);
42 }
43
44 return false;
45 }
46
47 if (isNonNullType(maybeSubType)) {
48 // If superType is nullable, maybeSubType may be non-null or nullable.
49 return isTypeSubTypeOf(schema, maybeSubType.ofType, superType);
50 } // If superType type is a list, maybeSubType type must also be a list.
51
52 if (isListType(superType)) {
53 if (isListType(maybeSubType)) {
54 return isTypeSubTypeOf(schema, maybeSubType.ofType, superType.ofType);
55 }
56
57 return false;
58 }
59
60 if (isListType(maybeSubType)) {
61 // If superType is not a list, maybeSubType must also be not a list.
62 return false;
63 } // If superType type is an abstract type, check if it is super type of maybeSubType.
64 // Otherwise, the child type is not a valid subtype of the parent type.
65
66 return (
67 isAbstractType(superType) &&
68 (isInterfaceType(maybeSubType) || isObjectType(maybeSubType)) &&
69 schema.isSubType(superType, maybeSubType)
70 );
71}
72/**
73 * Provided two composite types, determine if they "overlap". Two composite
74 * types overlap when the Sets of possible concrete types for each intersect.
75 *
76 * This is often used to determine if a fragment of a given type could possibly
77 * be visited in a context of another type.
78 *
79 * This function is commutative.
80 */
81
82export function doTypesOverlap(schema, typeA, typeB) {
83 // Equivalent types overlap
84 if (typeA === typeB) {
85 return true;
86 }
87
88 if (isAbstractType(typeA)) {
89 if (isAbstractType(typeB)) {
90 // If both types are abstract, then determine if there is any intersection
91 // between possible concrete types of each.
92 return schema
93 .getPossibleTypes(typeA)
94 .some((type) => schema.isSubType(typeB, type));
95 } // Determine if the latter type is a possible concrete type of the former.
96
97 return schema.isSubType(typeA, typeB);
98 }
99
100 if (isAbstractType(typeB)) {
101 // Determine if the former type is a possible concrete type of the latter.
102 return schema.isSubType(typeB, typeA);
103 } // Otherwise the types do not overlap.
104
105 return false;
106}