Type Generation
Automatic TypeScript type generation for server-side resolvers and client-side queries.
Overview
Nitro GraphQL automatically generates TypeScript types from your GraphQL schemas:
- Server Types: Use in resolvers and server code
- Client Types: Use in frontend components and queries
- External Service Types: For third-party GraphQL APIs
Server Types
Location
Generated at:
- Nitro:
.nitro/types/nitro-graphql-server.d.ts - Nuxt:
.nuxt/types/nitro-graphql-server.d.ts
Import Path
import type { Mutation, Post, Query, Resolvers, User } from '#graphql/server'Generated Types
From this schema:
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
}
input CreateUserInput {
name: String!
email: String!
}
type Query {
users: [User!]!
user(id: ID!): User
}
type Mutation {
createUser(input: CreateUserInput!): User!
}Generated types:
// Object types
export interface User {
id: string
name: string
email: string
posts: Post[]
}
export interface Post {
id: string
title: string
content: string
}
// Input types
export interface CreateUserInput {
name: string
email: string
}
// Query types
export interface Query {
users: User[]
user?: User | null
}
// Mutation types
export interface Mutation {
createUser: User
}
// Resolver types
export interface Resolvers {
Query?: QueryResolvers
Mutation?: MutationResolvers
User?: UserResolvers
Post?: PostResolvers
}Using Server Types
In resolvers:
import type { CreateUserInput, User } from '#graphql/server'
export const userMutations = defineMutation({
createUser: async (
_,
{ input }: { input: CreateUserInput }
): Promise<User> => {
const user: User = {
id: Date.now().toString(),
name: input.name,
email: input.email,
posts: [],
}
return user
},
})In other server files:
// server/utils/user-service.ts
import type { User } from '#graphql/server'
export async function findUser(id: string): Promise<User | null> {
// Implementation
return null
}Client Types
Location
Generated at:
- Nitro:
.nitro/types/nitro-graphql-client.d.ts - Nuxt:
.nuxt/types/nitro-graphql-client.d.ts
Import Path
import type { CreateUserMutation, GetUsersQuery } from '#graphql/client'How It Works
Client types are generated from your .graphql query files:
# app/graphql/users/get-users.graphql
query GetUsers {
users {
id
name
email
}
}Generated type:
export interface GetUsersQuery {
users: Array<{
id: string
name: string
email: string
}>
}Using Client Types
In Vue components:
<script setup lang="ts">
import type { GetUsersQuery } from '#graphql/client'
const { GetUsers } = useGraphql()
// Fully typed response
const { data } = await useAsyncData<GetUsersQuery>('users', () =>
GetUsers()
)
// data.value?.users is typed as User[]
</script>
<template>
<div v-for="user in data?.users" :key="user.id">
{{ user.name }}
</div>
</template>Query with Variables
# app/graphql/users/get-user.graphql
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
posts {
id
title
}
}
}Generated types:
export interface GetUserQueryVariables {
id: string
}
export interface GetUserQuery {
user?: {
id: string
name: string
email: string
posts: Array<{
id: string
title: string
}>
} | null
}Usage:
<script setup lang="ts">
import type { GetUserQuery, GetUserQueryVariables } from '#graphql/client'
const { GetUser } = useGraphql()
const userId = ref('1')
const { data } = await useAsyncData<GetUserQuery>(
'user',
() => GetUser({ id: userId.value })
)
</script>Mutation Types
# app/graphql/users/create-user.graphql
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
id
name
email
}
}Generated:
export interface CreateUserMutationVariables {
input: CreateUserInput
}
export interface CreateUserMutation {
createUser: {
id: string
name: string
email: string
}
}Usage:
const { CreateUser } = useGraphql()
const newUser = await CreateUser({
input: {
name: 'John Doe',
email: 'john@example.com',
}
})
// newUser is typed as CreateUserMutationExternal Service Types
Configuration
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
graphql: {
framework: 'graphql-yoga',
externalServices: [
{
name: 'github',
schema: 'https://api.github.com/graphql',
endpoint: 'https://api.github.com/graphql',
documents: ['app/graphql/github/**/*.graphql'],
},
],
},
},
})Generated Types
Location: .nuxt/types/nitro-graphql-client-github.d.ts
Import path:
import type {
GetRepositoryQuery,
SearchRepositoriesQuery
} from '#graphql/client/github'Using External Types
# app/graphql/github/get-repository.graphql
query GetRepository($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
id
name
description
stargazerCount
}
}<script setup lang="ts">
import type { GetRepositoryQuery } from '#graphql/client/github'
const { github } = useGraphql()
const { data } = await useAsyncData<GetRepositoryQuery>(
'repo',
() => github.GetRepository({
owner: 'unjs',
name: 'nitro'
})
)
</script>
<template>
<div v-if="data?.repository">
<h1>{{ data.repository.name }}</h1>
<p>{{ data.repository.description }}</p>
<p>⭐ {{ data.repository.stargazerCount }}</p>
</div>
</template>Type Generation Configuration
Disable Type Generation
// nitro.config.ts
export default defineNitroConfig({
graphql: {
framework: 'graphql-yoga',
types: {
server: false, // Don't generate server types
client: false, // Don't generate client types
external: false, // Don't generate external service types
},
},
})Custom Type Paths
export default defineNitroConfig({
graphql: {
framework: 'graphql-yoga',
types: {
server: 'types/graphql-server.d.ts',
client: 'types/graphql-client.d.ts',
external: 'types/graphql-{serviceName}.d.ts',
},
},
})Advanced Type Usage
Resolver Type Safety
Full type safety in resolvers:
import type { Resolvers } from '#graphql/server'
// Fully typed resolver map
const resolvers: Resolvers = {
Query: {
users: async () => {
// Return type is inferred as User[]
return []
},
user: async (_, { id }) => {
// id is typed as string
// Return type is User | null
return null
},
},
User: {
posts: async (parent) => {
// parent is typed as User
// Return type is Post[]
return []
},
},
}Context Typing
Extend context with custom types:
// server/graphql/context.ts
declare module 'h3' {
interface H3EventContext {
db: Database
auth?: {
userId: string
role: string
}
}
}Use in resolvers:
export const userQueries = defineQuery({
users: async (_, __, context) => {
// context.db is typed
// context.auth is typed
return await context.db.user.findMany()
},
})Partial Types
For field resolvers, use partial parent types:
import type { Post, User } from '#graphql/server'
export const postTypes = defineType({
Post: {
author: async (parent: Pick<Post, 'authorId'>) => {
// parent only needs authorId field
const user: User = await findUser(parent.authorId)
return user
},
},
})Type Generation Triggers
Types are regenerated when:
- Dev server starts - Initial type generation
- Schema files change -
.graphqlfiles inserver/graphql/ - Client query files change -
.graphqlfiles inapp/graphql/ - Config changes -
nitro.config.tsornuxt.config.ts
Manual Regeneration
Restart the dev server to force type regeneration:
# Stop server (Ctrl+C)
pnpm devTroubleshooting
Types not generating
Check:
- Files are in correct directories
- File extensions are correct (
.graphql,.resolver.ts) - No GraphQL syntax errors
- Restart dev server
Verify:
# Check if types file exists
ls -la .nitro/types/nitro-graphql-server.d.ts
ls -la .nuxt/types/nitro-graphql-server.d.tsImport errors
Problem: Cannot find module '#graphql/server'
Solutions:
- Restart TypeScript server in VS Code:
Cmd+Shift+P→ "TypeScript: Restart TS Server" - Restart dev server
- Check
.nitro/types/or.nuxt/types/directory exists
Type mismatches
Problem: Resolver types don't match schema
Solution: Types are generated from schema. If schema changes, types update automatically. Make sure to:
- Save schema files
- Wait for type regeneration (check console)
- Restart TypeScript server
IDE Support
VSCode
Install GraphQL extension for:
- Syntax highlighting
- Autocomplete
- Schema validation
- Type hints
Recommended: GraphQL: Language Feature Support
graphql.config.ts
Auto-generated for IDE support:
// graphql.config.ts (auto-generated)
export default {
schema: './server/graphql/**/*.graphql',
documents: './app/graphql/**/*.graphql',
}This enables:
- Schema validation
- Query validation
- Autocomplete in
.graphqlfiles