@@ -261,6 +261,7 @@ TypeDefinition :
261261- ObjectTypeDefinition
262262- InterfaceTypeDefinition
263263- UnionTypeDefinition
264+ - IntersectionTypeDefinition
264265- EnumTypeDefinition
265266- InputObjectTypeDefinition
266267
@@ -276,7 +277,7 @@ Scalars and Enums form the leaves in response trees; the intermediate levels are
276277` Object ` types, which define a set of fields, where each field is another type
277278in the system, allowing the definition of arbitrary type hierarchies.
278279
279- GraphQL supports two abstract types: interfaces and unions .
280+ GraphQL supports three abstract types: interfaces, unions and intersections .
280281
281282An ` Interface ` defines a list of fields; ` Object ` types and other Interface
282283types which implement this Interface are guaranteed to implement those fields.
@@ -287,6 +288,11 @@ A `Union` defines a list of possible types; similar to interfaces, whenever the
287288type system claims a union will be returned, one of the possible types will be
288289returned.
289290
291+ An ` Intersection ` defines a list of constraining abstract types. If a field
292+ claims it returns an Intersection type, it will return only types that are
293+ contained within all of the Intersections's Unions and types that implement all
294+ of the Intersection's Interfaces.
295+
290296Finally, oftentimes it is useful to provide complex structs as inputs to GraphQL
291297field arguments or variables; the ` Input Object ` type allows the schema to
292298define exactly what data is expected.
@@ -314,9 +320,9 @@ to arguments and variables as well as the values output by fields. These two
314320uses categorize types as _ input types_ and _ output types_ . Some kinds of types,
315321like Scalar and Enum types, can be used as both input types and output types;
316322other kinds of types can only be used in one or the other. Input Object types
317- can only be used as input types. Object, Interface, and Union types can only be
318- used as output types. Lists and Non-Null types may be used as input types or
319- output types depending on how the wrapped type may be used.
323+ can only be used as input types. Object, Interface, Union, and Intersection
324+ types can only be used as output types. Lists and Non-Null types may be used as
325+ input types or output types depending on how the wrapped type may be used.
320326
321327IsInputType(type) :
322328
@@ -332,7 +338,7 @@ IsOutputType(type) :
332338- If {type} is a List type or Non-Null type:
333339 - Let {unwrappedType} be the unwrapped type of {type}.
334340 - Return IsOutputType({unwrappedType})
335- - If {type} is a Scalar, Object, Interface, Union, or Enum type:
341+ - If {type} is a Scalar, Object, Interface, Union, Intersection, or Enum type:
336342 - Return {true}
337343- Return {false}
338344
@@ -706,8 +712,8 @@ Must only yield exactly that subset:
706712```
707713
708714A field of an Object type may be a Scalar , Enum , another Object type , an
709- Interface , or a Union . Additionally , it may be any wrapping type whose
710- underlying base type is one of those five .
715+ Interface , a Union , or an Intersection . Additionally , it may be any wrapping
716+ type whose underlying base type is one of those five .
711717
712718For example , the `Person ` type might include a `relationship `:
713719
@@ -928,7 +934,13 @@ IsValidImplementationFieldType(fieldType, implementedFieldType):
9289345. If {fieldType } is an Object or Interface type and {implementedFieldType } is
929935 an Interface type and {fieldType } declares it implements
930936 {implementedFieldType } then return {true }.
931- 6. Otherwise return {false }.
937+ 6. If {fieldType } is an IntersectionType and {implementedFieldType } is an Union
938+ type and {fieldType } is a member type of {implementedFieldType } then return
939+ {true }.
940+ 7. If {fieldType } is an IntersectionType and {implementedFieldType } is an
941+ Interface type and at least one of the members of {fieldType } declares it
942+ implements {implementedFieldType } then return {true }.
943+ 8. Otherwise return {false }.
932944
933945### Field Arguments
934946
@@ -977,7 +989,7 @@ May return the result:
977989```
978990
979991The type of an object field argument must be an input type (any type except an
980- Object, Interface, or Union type).
992+ Object, Interface, Union, or Intersection type).
981993
982994### Field Deprecation
983995
@@ -1054,8 +1066,8 @@ objects and interfaces can then implement these interfaces which requires that
10541066the implementing type will define all fields defined by those interfaces .
10551067
10561068Fields on a GraphQL interface have the same rules as fields on a GraphQL object ;
1057- their type can be Scalar , Object , Enum , Interface , or Union , or any wrapping
1058- type whose base type is one of those five .
1069+ their type can be Scalar , Object , Enum , Interface , Union , or Intersection , or
1070+ any wrapping type whose base type is one of those five .
10591071
10601072For example , an interface `NamedEntity ` may describe a required field and types
10611073such as `Person ` or `Business ` may then implement this interface to guarantee
@@ -1415,6 +1427,181 @@ Union type extensions have the potential to be invalid if incorrectly defined.
141514275. Any non -repeatable directives provided must not already apply to the original
14161428 Union type .
14171429
1430+ ## Intersections
1431+
1432+ IntersectionTypeDefinition : Description ? intersection Name Directives [Const ]?
1433+ IntersectionMemberTypes ?
1434+
1435+ IntersectionMemberTypes :
1436+
1437+ - IntersectionMemberTypes | NamedType
1438+ - = `|`? NamedType
1439+
1440+ GraphQL Intersections are higher order abstract types that represent objects
1441+ satisfying the requirements of all of the Intersection 's abstract member types .
1442+ Intersections combine the features of interfaces and unions ; the objects
1443+ represented by an Intersection must implement all of the Intersection 's
1444+ interfaces and must also be included within all of its unions .
1445+
1446+ Just as with unions , intersections do not directly define any fields , so **no **
1447+ fields may be queried on this type without the use of type refining fragments or
1448+ inline fragments (with the exception of the meta-field {\_\_typename}).
1449+
1450+ For example , we might define the following types :
1451+
1452+ ```graphql example
1453+ interface Link {
1454+ link : Downloadable
1455+ }
1456+
1457+ type SearchResultLink implements Link {
1458+ link : DownloadableSearchResult
1459+ }
1460+
1461+ interface Downloadable {
1462+ url : string
1463+ }
1464+
1465+ union SearchResult = Photo | Person
1466+
1467+ intersection DownloadableSearchResult = SearchResult & Downloadable
1468+
1469+ type Person implements Downloadable {
1470+ url : String
1471+ name : String
1472+ age : Int
1473+ }
1474+
1475+ type Photo implements Downloadable {
1476+ url : String
1477+ height : Int
1478+ width : Int
1479+ }
1480+
1481+ type SearchQuery {
1482+ firstDownloadableSearchResult : DownloadableSearchResult
1483+ }
1484+ ```
1485+
1486+ Because intersection `DownloadableSearchResult ` includes interface
1487+ `Downloadable ` as a constraining member type , the possible types of the
1488+ intersection implement the `Downloadable ` interface . The `link ` field within
1489+ `SearchResultLink ` therefore implements the `link ` field of interface `Link `.
1490+
1491+ Just as with unions , the below could be ambiguous and is invalid .
1492+
1493+ ```graphql counter -example
1494+ {
1495+ firstDownloadableSearchResult {
1496+ url
1497+ name
1498+ height
1499+ }
1500+ }
1501+ ```
1502+
1503+ A valid operation includes typed fragments (in this example, inline fragments):
1504+
1505+ ```graphql example
1506+ {
1507+ firstDownloadableSearchResult {
1508+ ... on Downloadable {
1509+ url
1510+ }
1511+ ... on Person {
1512+ name
1513+ }
1514+ ... on Photo {
1515+ height
1516+ }
1517+ }
1518+ }
1519+ ```
1520+
1521+ Intersection members may be defined with an optional leading `&` character to
1522+ aid formatting when representing a longer list of constraining types :
1523+
1524+ ```raw graphql example
1525+ intersection DownloadableSearchResult =
1526+ & Downloadable
1527+ & SearchResult
1528+ ```
1529+
1530+ Interfaces that are transitively included within an intersection (interfaces
1531+ implemented by an included interface) must also be included within the
1532+ intersection . For example , `AuthoredPublicContent ` cannot include `Authored `
1533+ without also including `Node `:
1534+
1535+ ```raw graphql example
1536+ interface Node {
1537+ id : ID !
1538+ }
1539+
1540+ interface Authored implements Node {
1541+ author : String
1542+ }
1543+
1544+ union PublicContent = Document | Image
1545+
1546+ intersection AuthoredPublicContent = PublicContent & Authored & Node
1547+ ```
1548+
1549+ **Result Coercion **
1550+
1551+ The intersection type should have some way of determining which object a given
1552+ result corresponds to . Once it has done so , the result coercion of the
1553+ intersection is the same as the result coercion of the object .
1554+
1555+ **Input Coercion **
1556+
1557+ Intersections are never valid inputs .
1558+
1559+ **Type Validation **
1560+
1561+ Intersection types have the potential to be invalid if incorrectly defined .
1562+
1563+ 1. An Intersection type must include one or more unique member types .
1564+ 2. The member types of a Intersection type must all be Interface or Union base
1565+ types ; Scalar , Enum , Object and other Intersection types must not be member
1566+ types of an Intersection . Similarly , wrapping types must not be member types
1567+ of an Intersection .
1568+ 3. For each member type of an Intersection type :
1569+ 1. Let this member type be {memberType }.
1570+ 2. If {memberType } is an interface , all interfaces that {memberType } declares
1571+ it implements must also be member types of the Intersection .
1572+
1573+ ### Intersection Extensions
1574+
1575+ IntersectionTypeExtension :
1576+
1577+ - extend intersection Name Directives [Const ]? IntersectionMemberTypes
1578+ - extend intersection Name Directives [Const ]
1579+
1580+ Intersection type extensions are used to represent an intersection type which
1581+ has been extended from some original intersection type . Similar to unions , this
1582+ might by utilized by a GraphQL service which is itself an extension of another
1583+ GraphQL service .
1584+
1585+ **Type Validation **
1586+
1587+ Intersection type extensions have the potential to be invalid if incorrectly
1588+ defined .
1589+
1590+ 1. The named type must already be defined and must be a Intersection type .
1591+ 2. The member types of a Intersection type must all be Interface or Union base
1592+ types ; Scalar , Enum , Object and other Intersection types must not be member
1593+ types of an Intersection . Similarly , wrapping types must not be member types
1594+ of an Intersection .
1595+ 3. For each member type of an Intersection type :
1596+ 1. Let this member type be {memberType }.
1597+ 2. If {memberType } is an interface , all interfaces that {memberType } declares
1598+ it implements must also be member types of the Intersection .
1599+ 4. All member types of an Intersection type extension must be unique .
1600+ 5. All member types of an Intersection type extension must not already be a
1601+ member of the original Intersection type .
1602+ 6. Any non -repeatable directives provided must not already apply to the original
1603+ Intersection type .
1604+
14181605## Enums
14191606
14201607EnumTypeDefinition :
@@ -1876,6 +2063,7 @@ TypeSystemDirectiveLocation : one of
18762063- `ARGUMENT_DEFINITION `
18772064- `INTERFACE `
18782065- `UNION `
2066+ - `INTERSECTION `
18792067- `ENUM `
18802068- `ENUM_VALUE `
18812069- `INPUT_OBJECT `
0 commit comments