Unions and interfaces
To query some fields only on a certain type you can use graphql fragments
In gqlts you can express the fragments for union and interface types using the on_
prefixed fields in a query
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
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
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)
}