JavaScript is required for this site to function.

Adding global TypeScript types and interfaces to Nuxt projects

In some cases, it can be useful or preferred to make certain types and interfaces globally accessible during development.

Where should the type live?

The important Nuxt 4 detail is context. The app, server, and shared parts of the project have separate TypeScript contexts.

  • app: If the type is only for Vue components, composables, pages, and other app code, put it under app/, for example app/types/component-props.ts.
  • server: If the type is only for server routes or Nitro code, put it under server/, for example server/types/api-response.ts.
  • shared: If the type is used by both app and server code, put it under shared/, for example shared/types/links.ts, or for ambient globals, shared/types/global.d.ts.

A global.d.ts file is ambient in the context where it lives. app/types/global.d.ts is for app code, server/types/global.d.ts is for server code, and shared/types/global.d.ts is for both.

Ambient global declarations

Ambient means TypeScript can see the type without an import. In this post, that means a declaration file with types or interfaces that are not exported.

When you need a type to be available in both the Vue app and the Nitro server in a Nuxt 4 project, you could start with shared/types/global.d.ts.

shared/types/global.d.ts
TypeScript
interface LinksObject {
  count: number
  links: string[]
}
type StandardSize = 'l' | 'm' | 's'

Do not add export before the type or interface if you want the names to stay ambient.

A more explicit option

For normal .ts files, I usually export the types. The mental model is cleaner: the type lives in a named file, and the dependency is easier to see.

Nuxt can auto-import exported types from files directly inside shared/types, but an explicit import is still valid and often easier to read.

shared/types/links.ts
TypeScript
export interface LinksObject {
  count: number
  links: string[]
}

export type StandardSize = 'l' | 'm' | 's'

The Nuxt docs note one scanning detail that is easy to miss: only files directly inside shared/utils and shared/types are auto-imported by default. If you put files deeper inside nested folders, you either need imports or configure the relevant import directories.

Should everything be global?

No. Global ambient types can be convenient, but some would say they are confusing and too magical. I do not use them very much to be honest. When doing agentic coding, you notice that AI models also prefer explicit imports; it seems to help them get the context right.

If a type belongs to one feature, keep it close to that feature. Use ambient globals when the convenience is worth the tradeoff.

Continue reading