Is your feature request related to a problem? Please describe.
Interfaces & Unions are currently not fully supported.
Describe the solution you'd like
import {app, ID} from '@getcronit/pylon'
type Node = User | Post
interface User {
id: ID
name: string
}
interface Post {
id: ID
title: string
}
const nodes: Node[] = [
{
id: '1',
name: 'John Doe'
},
{
id: '2',
name: 'Jane Doe'
},
{
id: '3',
title: 'Hello, World!'
},
{
id: '4',
title: 'Hello, Pylon!'
}
]
export const graphql = {
Query: {
post: (id: ID) => {
return nodes.find(node => node.id === id && 'title' in node) as Post
},
user: (id: ID) => {
return nodes.find(node => node.id === id && 'name' in node) as User
},
node: (id: ID): Node => {
const node = nodes.find(node => node.id === id)
if (!node) {
throw new Error('Node not found')
}
return node
}
},
Mutation: {}
}
export default app
This will result in the following schema:
interface Node {
id: ID!
}
type User implements Node {
id: ID!
name: String!
}
type Post implements Node {
id: ID!
title: String!
}
type Query {
post(id: ID!): Post
user(id: ID!): User
node(id: ID!): Node
}
And can be queried like this:
{
node(id: "1") {
__typename
id
... on User {
name
}
... on Post{
title
}
}
}
Whenever you use a TypeScript union like type Foo = Bar | Baz Pylon will create a Foo interface that is implemented by Bar and Baz.
The __resolveType function that you would typically need to support interfaces, for example when using apollo server , is not required. Pylon will automatically resolve the correct type for you.
Whenever there are shared properties in a union, Pylon will create a interface for you.
type Bar = {
id: ID
title: string
}
type Foo = {
id: ID
name: string
}
type Example = Foo | Bar
This will generate the following GraphQL schema:
interface Example {
id: ID!
}
type Foo implements Example {
id: ID!
name: String!
}
type Bar implements Example {
id: ID!
title: String!
}
But if the properties are not shared, Pylon will create a union type for you.
type Foo = {
birthday: Date
}
type Bar = {
age: number
}
type Example = Foo | Bar
This will generate the following GraphQL schema:
type Foo {
birthday: Date
}
type Bar {
age: Int
}
union Example = Foo | Bar
interface NodeInterface {
id: string
}
class NodeC1lass implements NodeInterface {
constructor(public id: string) {}
}
class NodeC2lass implements NodeInterface {
constructor(public id: string) {}
public extra = 'extra'
}
const nodes = [
new NodeC1lass('1'),
new NodeC2lass('2'),
]
export const graphql = {
Query: {
node: (id: ID) => {
return nodes.find(node => node.id === id)
}
}
}
Even this will work through Pylons type inference and name generation:
Is your feature request related to a problem? Please describe. Interfaces & Unions are currently not fully supported.
Describe the solution you'd like
This will result in the following schema:
And can be queried like this:
Whenever you use a TypeScript union like
type Foo = Bar | Baz
Pylon will create aFoo
interface that is implemented byBar
andBaz
. The__resolveType
function that you would typically need to support interfaces, for example when using apollo server , is not required. Pylon will automatically resolve the correct type for you.Whenever there are shared properties in a union, Pylon will create a interface for you.
This will generate the following GraphQL schema:
But if the properties are not shared, Pylon will create a union type for you.
This will generate the following GraphQL schema:
Even this will work through Pylons type inference and name generation:
This will generate a interface and two types with generated names
The graphql specs allow for mulitple implements
This would be the equivalent to: