Type Definitions API Reference
Complete reference for TypeScript types generated and used by Nitro GraphQL.
Generated Types Overview
Nitro GraphQL automatically generates TypeScript types in three categories:
- Server Types (
#graphql/server) - For resolver implementations - Client Types (
#graphql/client) - For frontend queries/mutations - External Types (
#graphql/client/{serviceName}) - For external GraphQL services
Server Types
Generated at: .nitro/types/nitro-graphql-server.d.ts (or .nuxt/types/)
Import via: #graphql/server
Primary Exports
Resolvers
Complete resolver type with all GraphQL types and their field resolvers.
import type { Resolvers } from '#graphql/server'
export const myResolvers: Resolvers = defineResolver({
Query: { /* ... */ },
Mutation: { /* ... */ },
User: { /* ... */ }
})Type Definition:
interface Resolvers<ContextType = H3Event, ParentType = ResolversParentTypes> {
Query?: QueryResolvers<ContextType>
Mutation?: MutationResolvers<ContextType>
Subscription?: SubscriptionResolvers<ContextType>
[CustomType: string]: TypeResolvers<ContextType, ParentType>
}QueryResolvers
Type for Query field resolvers.
import type { QueryResolvers } from '#graphql/server'
export const queries: QueryResolvers = defineQuery({
user: async (_parent, { id }, context) => {
return await context.db.users.findById(id)
},
users: async (_parent, args, context) => {
return await context.db.users.findAll()
}
})Type Definition:
interface QueryResolvers<ContextType = H3Event, ParentType = {}> {
[fieldName: string]: Resolver<ReturnType, ParentType, ContextType, Args>
}MutationResolvers
Type for Mutation field resolvers.
import type { MutationResolvers } from '#graphql/server'
export const mutations: MutationResolvers = defineMutation({
createUser: async (_parent, { input }, context) => {
return await context.db.users.create(input)
}
})SubscriptionResolvers
Type for Subscription field resolvers.
import type { SubscriptionResolvers } from '#graphql/server'
export const subscriptions: SubscriptionResolvers = defineSubscription({
messageAdded: {
subscribe: (_parent, _args, context) => {
return context.pubsub.asyncIterator(['MESSAGE_ADDED'])
}
}
})ResolversTypes
Union of all possible GraphQL types in your schema.
import type { ResolversTypes } from '#graphql/server'
// Example: User type from schema
type User = ResolversTypes['User']
// { id: string; name: string; email: string; ... }
// Example: Query return type
type UsersQueryResult = ResolversTypes['UsersResult']Generated Structure:
interface ResolversTypes {
String: string
Int: number
Float: number
Boolean: boolean
ID: string
DateTime: Date
JSON: any
Query: {}
Mutation: {}
User: User
Post: Post
// ... all your GraphQL types
}ResolversParentTypes
Parent types for field resolvers (usually same as ResolversTypes).
import type { ResolversParentTypes } from '#graphql/server'
type PostParent = ResolversParentTypes['Post']Specific Type Resolvers
For each GraphQL type in your schema, a specific resolver type is generated:
import type { PostResolvers, UserResolvers } from '#graphql/server'
export const userTypeResolvers: UserResolvers = defineType({
User: {
fullName: parent => `${parent.firstName} ${parent.lastName}`,
posts: async (parent, _args, context) => {
return await context.db.posts.findByUserId(parent.id)
}
}
})
export const postTypeResolvers: PostResolvers = defineType({
Post: {
author: async (parent, _args, context) => {
return await context.db.users.findById(parent.authorId)
}
}
})Field Argument Types
For each field with arguments, specific argument types are generated:
import type {
MutationCreateUserArgs,
QueryUserArgs,
QueryUsersArgs
} from '#graphql/server'
// Field: Query.user(id: ID!): User
interface QueryUserArgs {
id: string
}
// Field: Query.users(filter: UserFilter, limit: Int): [User!]!
interface QueryUsersArgs {
filter?: UserFilter
limit?: number
}
// Field: Mutation.createUser(input: CreateUserInput!): User!
interface MutationCreateUserArgs {
input: CreateUserInput
}Input Types
All GraphQL input types are generated as TypeScript types:
import type {
CreateUserInput,
UpdateUserInput,
UserFilter
} from '#graphql/server'
// GraphQL:
// input CreateUserInput {
// name: String!
// email: String!
// age: Int
// }
interface CreateUserInput {
name: string
email: string
age?: number | null
}
// GraphQL:
// input UserFilter {
// search: String
// role: UserRole
// isActive: Boolean
// }
interface UserFilter {
search?: string | null
role?: UserRole | null
isActive?: boolean | null
}Enum Types
All GraphQL enums are generated as TypeScript enums:
import type { PostStatus, UserRole } from '#graphql/server'
// GraphQL:
// enum UserRole {
// ADMIN
// USER
// GUEST
// }
enum UserRole {
ADMIN = 'ADMIN',
USER = 'USER',
GUEST = 'GUEST'
}
// GraphQL:
// enum PostStatus {
// DRAFT
// PUBLISHED
// ARCHIVED
// }
enum PostStatus {
DRAFT = 'DRAFT',
PUBLISHED = 'PUBLISHED',
ARCHIVED = 'ARCHIVED'
}Scalar Types
Custom scalars are mapped to TypeScript types:
import type { Scalars } from '#graphql/server'
interface Scalars {
ID: string
String: string
Int: number
Float: number
Boolean: boolean
DateTime: Date // Custom scalar
JSON: any // Custom scalar
Upload: File // Custom scalar
}You can customize scalar mappings in configuration:
// nitro.config.ts
export default defineNitroConfig({
graphql: {
framework: 'graphql-yoga',
codegen: {
server: {
scalars: {
DateTime: 'Date',
JSON: '{ [key: string]: any }',
Upload: 'File'
}
}
}
}
})Context Type
The context type is automatically inferred from your context augmentation:
// server/graphql/context.ts
import type { Database } from '../utils/useDb'
declare module 'h3' {
interface H3EventContext {
db: Database
auth?: {
userId: string
user: {
id: string
role: 'ADMIN' | 'USER'
}
}
}
}Then in resolvers, the context is fully typed:
import type { QueryResolvers } from '#graphql/server'
export const queries: QueryResolvers = defineQuery({
currentUser: async (_parent, _args, context) => {
// context.db is typed as Database
// context.auth is typed with optional user
if (!context.auth?.userId) {
throw new Error('Not authenticated')
}
return await context.db.users.findById(context.auth.userId)
}
})Module Configuration Type
Access to the Nitro GraphQL configuration:
import type { NPMConfig } from '#graphql/server'
// Runtime access to config
const config: NPMConfig = {
framework: 'graphql-yoga',
endpoint: { /* ... */ },
// ...
}Client Types
Generated at: .nitro/types/nitro-graphql-client.d.ts (or .nuxt/types/)
Import via: #graphql/client
Primary Exports
Client types are generated from your GraphQL documents (queries/mutations).
Operation Result Types
For each operation in your .graphql files:
# app/graphql/users.graphql
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
posts {
id
title
}
}
}
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
id
name
email
}
}Generated types:
import type {
CreateUserMutation,
CreateUserMutationVariables,
GetUserQuery,
GetUserQueryVariables
} from '#graphql/client'
// Query result type
interface GetUserQuery {
user: {
id: string
name: string
email: string
posts: Array<{
id: string
title: string
}>
} | null
}
// Query variables type
interface GetUserQueryVariables {
id: string
}
// Mutation result type
interface CreateUserMutation {
createUser: {
id: string
name: string
email: string
}
}
// Mutation variables type
interface CreateUserMutationVariables {
input: CreateUserInput
}Fragment Types
Fragments are also typed:
fragment UserFields on User {
id
name
email
createdAt
}
query GetUsers {
users {
...UserFields
}
}Generated:
import type { GetUsersQuery, UserFieldsFragment } from '#graphql/client'
interface UserFieldsFragment {
id: string
name: string
email: string
createdAt: string
}
interface GetUsersQuery {
users: Array<UserFieldsFragment>
}SDK Types
If SDK generation is enabled, typed SDK functions are available:
import { getSdk } from '#graphql/client'
// Get SDK with fetcher
const sdk = getSdk(fetcher)
// Fully typed methods
const user = await sdk.GetUser({ id: '123' })
// ^? GetUserQuery
const newUser = await sdk.CreateUser({
input: { name: 'John', email: 'john@example.com' }
})
// ^? CreateUserMutationInput Types (Client)
Client input types match server types but use client-side scalar mappings:
import type { CreateUserInput } from '#graphql/client'
interface CreateUserInput {
name: string
email: string
age?: number | null
}
// Note: DateTime scalars might be strings on client
interface CreatePostInput {
title: string
content: string
publishedAt?: string | null // DateTime as string
}Configure client scalar mappings:
export default defineNitroConfig({
graphql: {
framework: 'graphql-yoga',
codegen: {
client: {
scalars: {
DateTime: 'string', // ISO string on client
JSON: 'any'
}
}
}
}
})External Service Types
Generated at: .nitro/types/nitro-graphql-client-{serviceName}.d.ts
Import via: #graphql/client/{serviceName}
Example: GitHub Service
// nitro.config.ts
export default defineNitroConfig({
graphql: {
framework: 'graphql-yoga',
externalServices: [
{
name: 'github',
schema: 'https://api.github.com/graphql',
endpoint: 'https://api.github.com/graphql'
}
]
}
})# app/graphql/github/viewer.graphql
query GetViewer {
viewer {
login
name
email
repositories(first: 10) {
nodes {
name
description
}
}
}
}Generated types:
import type {
GetViewerQuery,
GetViewerQueryVariables
} from '#graphql/client/github'
interface GetViewerQuery {
viewer: {
login: string
name: string | null
email: string
repositories: {
nodes: Array<{
name: string
description: string | null
} | null> | null
}
}
}
interface GetViewerQueryVariables {}With SDK:
import { getSdk } from '#graphql/client/github'
const githubSdk = getSdk(fetcher)
const viewer = await githubSdk.GetViewer()
// ^? GetViewerQueryStandard Schema Types
For runtime validation with defineSchema():
import type { StandardSchemaV1 } from 'nitro-graphql'
// Standard Schema interface
interface StandardSchemaV1<Input = unknown, Output = Input> {
readonly '~standard': StandardSchemaV1.Props<Input, Output>
}
// Standard Schema properties
namespace StandardSchemaV1 {
interface Props<Input = unknown, Output = Input> {
readonly version: 1
readonly vendor: string
readonly validate: (
value: unknown
) => Result<Output> | Promise<Result<Output>>
readonly types?: Types<Input, Output> | undefined
}
// Validation result
type Result<Output> = SuccessResult<Output> | FailureResult
interface SuccessResult<Output> {
readonly value: Output
readonly issues?: undefined
}
interface FailureResult {
readonly issues: ReadonlyArray<Issue>
}
interface Issue {
readonly message: string
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined
}
// Type inference
type InferInput<Schema extends StandardSchemaV1> = NonNullable<
Schema['~standard']['types']
>['input']
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<
Schema['~standard']['types']
>['output']
}Usage with validators:
import type { StandardSchemaV1 } from 'nitro-graphql'
import * as v from 'valibot'
const userSchema = v.object({
name: v.string(),
email: v.pipe(v.string(), v.email())
})
// userSchema satisfies StandardSchemaV1
export default defineSchema({
CreateUserInput: userSchema
})
// Type inference
type UserInput = StandardSchemaV1.InferInput<typeof userSchema>
// { name: string, email: string }Resolver Type Utilities
Resolver Function Type
type Resolver<TReturn, TParent = {}, TContext = H3Event, TArgs = {}>
= | ResolverFn<TReturn, TParent, TContext, TArgs>
| ResolverWithResolve<TReturn, TParent, TContext, TArgs>
type ResolverFn<TReturn, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => TReturn | Promise<TReturn>
// For subscriptions
interface ResolverWithResolve<TReturn, TParent, TContext, TArgs> {
resolve: ResolverFn<TReturn, TParent, TContext, TArgs>
subscribe: SubscriptionSubscribeFn<any, TParent, TContext, TArgs>
}Field Resolver Type
type FieldResolver<
TParent,
TReturn,
TContext = H3Event,
TArgs = {}
> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => TReturn | Promise<TReturn>Subscription Resolver Type
type SubscriptionSubscribeFn<TReturn, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => AsyncIterable<TReturn> | Promise<AsyncIterable<TReturn>>Best Practices
1. Import Types from Virtual Modules
Always use the virtual module imports for generated types:
import type { GetUserQuery } from '#graphql/client'
// ✅ Correct
import type { QueryResolvers, Resolvers } from '#graphql/server'
// ❌ Wrong
import type { Resolvers } from '.nitro/types/nitro-graphql-server'2. Use Type Annotations
Explicitly type your resolvers for better IDE support:
import type { MutationResolvers, QueryResolvers } from '#graphql/server'
export const queries: QueryResolvers = defineQuery({
// Fully typed!
})
export const mutations: MutationResolvers = defineMutation({
// Fully typed!
})3. Leverage Context Types
Define your context once and get full type safety:
// server/graphql/context.ts
declare module 'h3' {
interface H3EventContext {
db: Database
auth?: AuthContext
}
}
// All resolvers automatically have typed context
export const queries = defineQuery({
user: async (_parent, { id }, context) => {
// context.db is fully typed
return await context.db.users.findById(id)
}
})4. Use Fragment Types for Consistency
import type { UserFieldsFragment } from '#graphql/client'
function formatUser(user: UserFieldsFragment) {
return {
displayName: user.name,
email: user.email
}
}5. Type-Safe Error Handling
import type { QueryResolvers } from '#graphql/server'
import { GraphQLError } from 'graphql'
export const queries: QueryResolvers = defineQuery({
user: async (_parent, { id }, context) => {
const user = await context.db.users.findById(id)
if (!user) {
throw new GraphQLError('User not found', {
extensions: {
code: 'NOT_FOUND',
id
}
})
}
return user
}
})Type Generation Configuration
Customize type generation via codegen options:
export default defineNitroConfig({
graphql: {
framework: 'graphql-yoga',
codegen: {
server: {
// Custom context type
contextType: '~/server/graphql/context#GraphQLContext',
// Scalar mappings
scalars: {
DateTime: 'Date',
JSON: '{ [key: string]: any }',
Upload: 'File'
},
// Use type imports
useTypeImports: true,
// Add explicit types
addExplicitTypes: true
},
client: {
// Client scalar mappings
scalars: {
DateTime: 'string',
JSON: 'any'
},
// Use type imports
useTypeImports: true
}
}
}
})