Unions and interfaces

To query some fields only on a certain type you can use graphql fragments
In genql you can express the fragments for union and interface types using the on_ prefixed fields in a query
typescript
import { createClient } from './generated' const client = createClient() const { account } = await client.query({ account: { __typename: true, commonProp: true, on_User: { id: true, name: true, }, on_Guest: { surname: true, }, }, }) // common prop will be available without type guards console.log(account?.commonProp)

Restrict an union to the correct sub type

You can check the value of __typename to restrict an union type to one of its sub types and let typescript infer its correct fields
typescript
const { account } = await client.query({ account: { __typename: true, on_User: { id: true, name: true, }, }, }) if (account.__typename === 'User') { // now account has type User console.log(account.name) console.log(account.id) }

Type Guards

Union and interfaces are translated to typescript using union types
After you do a query on an union type, you can use the exported typescript guards to check the type of an object (remember to query the __typename field when you use type guards)
remember to query the __typename field when you use type guards or they will throw an error
typescript
import { createClient, isUser, isGuest } from './generated' const client = createClient() const { account } = await client.query({ account: { __typename: true, on_User: { id: true, name: true, }, on_Guest: { surname: true, }, }, }) if (isUser(account)) { // now account has type User console.log(account.name) console.log(account.id) } // another way to do the same without guards, typescript will infer the type to User if (account.__typename === 'User') { // now account has type User console.log(account.name) console.log(account.id) } if (isGuest(account)) { // now account has type Guest console.log(account.surname) }

Powered by Notaku