Skip to content

introduce new Intersection type #3550

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs-old/APIReference-GraphQL.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ _Type Definitions_
A union type within GraphQL that defines a list of implementations.
</a>
</li>
<li>
<a href="../type/#graphqlintersectiontype">
<pre>class GraphQLIntersectionType</pre>
An intersection type within GraphQL that defines a list of constraining types.
</a>
</li>
<li>
<a href="../type/#graphqlenumtype">
<pre>class GraphQLEnumType</pre>
Expand Down
6 changes: 6 additions & 0 deletions docs-old/APIReference-TypeSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ _Definitions_
A union type within GraphQL that defines a list of implementations.
</a>
</li>
<li>
<a href="#graphqlintersectiontype">
<pre>class GraphQLIntersectionType</pre>
An intersection type within GraphQL that defines a list of constraining types.
</a>
</li>
<li>
<a href="#graphqlenumtype">
<pre>class GraphQLEnumType</pre>
Expand Down
12 changes: 12 additions & 0 deletions src/__testUtils__/kitchenSinkSDL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ extend union Feed = Photo | Video

extend union Feed @onUnion

intersection Resource = Feed & Node

intersection AnnotatedIntersection @onIntersection = Feed & Node

intersection AnnotatedIntersectionTwo @onIntersection = Feed & Node

intersection UndefinedIntersection

extend intersection Resource = Media & Accessible

extend intersection Resource @onIntersection

scalar CustomScalar

scalar AnnotatedScalar @onScalar
Expand Down
161 changes: 161 additions & 0 deletions src/execution/__tests__/abstract-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { parse } from '../../language/parser';
import {
assertInterfaceType,
GraphQLInterfaceType,
GraphQLIntersectionType,
GraphQLList,
GraphQLObjectType,
GraphQLUnionType,
Expand Down Expand Up @@ -352,6 +353,94 @@ describe('Execute: Handles execution of abstract types', () => {
});
});

it('isTypeOf used to resolve runtime type for Intersection', async () => {
const DogType = new GraphQLObjectType({
name: 'Dog',
isTypeOf(obj, context) {
const isDog = obj instanceof Dog;
return context.async ? Promise.resolve(isDog) : isDog;
},
interfaces: () => [PetType],
fields: {
name: { type: GraphQLString },
woofs: { type: GraphQLBoolean },
},
});

const CatType = new GraphQLObjectType({
name: 'Cat',
isTypeOf(obj, context) {
const isCat = obj instanceof Cat;
return context.async ? Promise.resolve(isCat) : isCat;
},
interfaces: () => [PetType],
fields: {
name: { type: GraphQLString },
meows: { type: GraphQLBoolean },
},
});

const PetType = new GraphQLInterfaceType({
name: 'Pet',
fields: {
name: { type: GraphQLString },
},
});

const CatOrDogType = new GraphQLUnionType({
name: 'CatOrDog',
types: [DogType, CatType],
});

const CatOrDogPetType = new GraphQLIntersectionType({
name: 'CatOrDogPet',
types: [CatOrDogType, PetType],
});

const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: {
catOrDogPets: {
type: new GraphQLList(CatOrDogPetType),
resolve() {
return [new Dog('Odie', true), new Cat('Garfield', false)];
},
},
},
}),
});

const query = `{
catOrDogPets {
... on Pet {
name
}
... on Dog {
woofs
}
... on Cat {
meows
}
}
}`;

expect(await executeQuery({ schema, query })).to.deep.equal({
data: {
catOrDogPets: [
{
name: 'Odie',
woofs: true,
},
{
name: 'Garfield',
meows: false,
},
],
},
});
});

it('resolveType can throw', async () => {
const PetType = new GraphQLInterfaceType({
name: 'Pet',
Expand Down Expand Up @@ -497,6 +586,78 @@ describe('Execute: Handles execution of abstract types', () => {
});
});

it('resolve Intersection type using __typename on source object', async () => {
const schema = buildSchema(`
type Query {
catOrDogPets: [CatOrDogPet]
}

union CatOrDog = Cat | Dog

interface Pet {
name: String
}

intersection CatOrDogPet = CatOrDog & Pet

type Cat implements Pet {
name: String
meows: Boolean
}

type Dog implements Pet {
name: String
woofs: Boolean
}
`);

const query = `
{
catOrDogPets {
... on Pet {
name
}
... on Dog {
woofs
}
... on Cat {
meows
}
}
}
`;

const rootValue = {
catOrDogPets: [
{
__typename: 'Dog',
name: 'Odie',
woofs: true,
},
{
__typename: 'Cat',
name: 'Garfield',
meows: false,
},
],
};

expect(await executeQuery({ schema, query, rootValue })).to.deep.equal({
data: {
catOrDogPets: [
{
name: 'Odie',
woofs: true,
},
{
name: 'Garfield',
meows: false,
},
],
},
});
});

it('resolve Interface type using __typename on source object', async () => {
const schema = buildSchema(`
type Query {
Expand Down
Loading