graphql / graphql/graphql-spec

union does not allow sub-union or covariance

Open
#711 4 comments 7 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
14.6k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

In RDF it's quite common to use subclasses, and somewhat common to use union types (eg `schema:rangeIncludes` states a field can take values from several different classes; `owl:unionOf` does a similar thing).

RDF is based on formal logic, so it considers classes (types) as **sets**. In this interpretation, it's clear how to determine subtypes (especially useful for field **covariance**). Eg

```graphql
interface A {}
interface B {}
interface C {}
type A1 implements A {}
type B1 implements B {}
type C1 implements C {}
union U1=A|B|C
union U2=A1|B1|C1 # subtype of U1 because it uses subclasses
union U3=A|B # subtype of U1 because it uses fewer union members
union U4=A|A1|B|C # equivalent to U1 because A subsumes A1
union U5=A1|B1 # subtype of U1, U2 and U3
```

But the spec says:
- [fieldType (child) is an Object type and implementedFieldType (parent) is a Union type and fieldType is a possible type of implementedFieldType](https://spec.graphql.org/draft/#sel-HAHZhCJCHCAACKB5lK)
- [Member types of a Union type must all be Object base types; Scalar, Interface and Union types must not be member types of a Union](https://spec.graphql.org/draft/#sel-HAHdfFDABEBlEn_b)

This means that `U1, U3, U4` are not allowed, and neither of them can be used in an object type field.

This creates severe limitations on what polymorphic constructs (in particular RDF constructs) can be mapped to GraphQL.

(I searched here for "union but not 'input union'" and came up only with #518 as a possibly related issue. cc @derek-miller @mavilein)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.