如何在 Nuxt 3 中扩展 H3Event 上下文类型

Eva*_*ers 3 typescript nuxt.js nuxtjs3

在 Nuxt 3 文档中,有一个示例展示了如何使用服务器中间件通过以下方式使用附加信息来注释请求event.context

export default defineEventHandler((event) => {
  event.context.auth = { user: 123 }
})
Run Code Online (Sandbox Code Playgroud)

但是,没有示例说明如何为此进行相应的 TypeScript 键入。我宁愿我event.context.auth不成为一个any类型。

标准 TypeScript 库类型扩展方法在这里似乎无法正常工作。我尝试制作一个shims.d.ts包含以下内容的内容:

declare module 'h3' {
  interface H3EventContext {
    auth: AuthSession
  }
}
Run Code Online (Sandbox Code Playgroud)

然而,这破坏了函数的类型推断defineEventHandler,使所有event参数都变成隐式的any。如何在不破坏内容的情况下声明我的事件上下文类型?

U-D*_*Dev 6

为此,我们可以使用 TypeScript 的声明合并。由于 Nuxth3在幕后使用模块,因此我们需要扩展h3模块并添加自定义类型。我们可以这样做:

type MyFancyAuthType = {
  user: number
}

declare module 'h3' {
  interface H3EventContext {
    auth: MyFancyAuthType;
    // any other type
  }
}

export default defineEventHandler((event) => {
  // Here you will be able to access .auth on context with proper intellisense
  event.context.auth = { user: 123 }
})
Run Code Online (Sandbox Code Playgroud)

您可以在单独的文件中明确定义它,例如shim.d.ts. 如果你这样做,你需要告诉 TypeScript 编译器。

tsconfig.json

{
  ...
  "files": ["shim.d.ts"]
  ...
}
Run Code Online (Sandbox Code Playgroud)

此外,您需要确保必须添加export default {}. 应该是这样的:

shim.d.ts

...
declare module 'h3' {
  ...
}

// this is important
export default {};
Run Code Online (Sandbox Code Playgroud)

请注意,虽然这是 TypeScript 社区中广泛采用的约定,但它并不是 TypeScript 本身记录的官方语言功能。