Advanced

Type helpers

Reuse generated OpenAPI types in your application

NuxtOpenFetch exposes both convenient request and response helpers and the complete types generated from each OpenAPI schema. You can use them outside the generated fetch clients, without running another code generator.

Request and response helpers

For every client, NuxtOpenFetch generates five helpers in #open-fetch. Their names start with the PascalCase client name:

HelperExtracts
[Client]FetchOptionsFetch options for an OpenAPI path
[Client]RequestQueryQuery parameters
[Client]RequestPathPath parameters
[Client]RequestBodyJSON request body
[Client]ResponseJSON response body
import type {
  PetsRequestBody,
  PetsRequestPath,
  PetsRequestQuery,
  PetsResponse
} from '#open-fetch'

type FindByStatusQuery = PetsRequestQuery<'findPetsByStatus'>
type GetPetPath = PetsRequestPath<'getPetById'>
type CreatePetBody = PetsRequestBody<'addPet'>
type PetResponse = PetsResponse<'getPetById'>

[Client]FetchOptions accepts an OpenAPI path and keeps its method, parameters, and request body in sync. This is useful for wrappers that receive the path and options separately:

import type { PetsFetchOptions } from '#open-fetch'
import type { paths as PetsPaths } from '#open-fetch-schemas/pets'

type PetsPath = Extract<keyof PetsPaths, string>

interface FormProps<Path extends PetsPath> {
  path: Path
  options: PetsFetchOptions<Path>
}

[Client]Response uses the successful response status by default. Pass a status code as its second type argument to select a specific response:

type NotFound = PetsResponse<'getPetById', 404>

The helpers are useful when typing state, component props, or functions that prepare data for a request:

import type { PetsRequestQuery, PetsResponse } from '#open-fetch'

type Status = PetsRequestQuery<'findPetsByStatus'>['status']

const status = ref<Status>('available')

function addStockStatus(data: PetsResponse<'findPetsByStatus'>) {
  return data.map(item => ({
    ...item,
    inStock: item.status === 'available'
  }))
}

const { data } = await usePets('/pet/findByStatus', {
  immediate: false,
  query: {
    status,
  },
  transform: addStockStatus
})

Schema types

The complete output from openapi-typescript is available from #open-fetch-schemas/[client]. It includes the generated paths, operations, and components types:

import type { components, operations, paths } from '#open-fetch-schemas/pets'

type PetPath = keyof paths
type GetPetOperation = operations['getPetById']
type Pet = components['schemas']['Pet']

Schemas declared under components.schemas are additionally exported as top-level types with a Schema prefix:

import type { SchemaPet, SchemaUser } from '#open-fetch-schemas/pets'
The import suffix is the client name from openFetch.clients. For a client named api, import from #open-fetch-schemas/api.

Typed paths outside the client

You can restrict a path to your OpenAPI schema when building a URL yourself or passing it elsewhere:

<script setup lang="ts">
import type { paths as ApiPaths } from '#open-fetch-schemas/api'

function useApiPath(path: keyof ApiPaths) {
  const baseURL = useRuntimeConfig().public.openFetch.api.baseURL
  return `${baseURL.replace(/\/$/, '')}/${path.replace(/^\//, '')}`
}
</script>

<template>
  <FileUpload
    :url="useApiPath('/v1/files')"
  />
</template>

Dynamic paths

By default, OpenAPI paths containing parameters are represented as templates such as /v1/files/{fileId}. The pathParamsAsTypes option can represent them as TypeScript template literal types:

nuxt.config.ts
export default defineNuxtConfig({
  openFetch: {
    openAPITS: {
      pathParamsAsTypes: true
    },
    clients: {
      api: {
        baseURL: 'http://localhost:1234'
      }
    }
  }
})

The same helper then accepts concrete parameter values while continuing to reject paths absent from the schema:

const fileId = 'file-123'
const fileURL = useApiPath(`/v1/files/${fileId}`)
pathParamsAsTypes can cause ambiguous types when dynamic routes overlap. It is not currently recommended. See issue #106 for details.
Copyright © 2023 - 2026