Bug
When registering the plugin with namespace option, fastify.jwt becomes a { [namespace]: JWT } map at runtime. However, TypeScript always types it as JWT (the single decorator shape).
Current type declaration (types/jwt.d.ts:16-18):
interface FastifyInstance {
jwt: fastifyJwt.JWT // hardcoded — ignores namespace mode
}
Reproduction
import fastify from 'fastify'
import jwt from '@fastify/jwt'
const app = fastify()
app.register(jwt, { secret: 'auth-secret', namespace: 'auth' })
app.register(jwt, { secret: 'admin-secret', namespace: 'admin' })
app.ready().then(() => {
// Runtime: works ✅
console.log(app.jwt.auth.sign({ sub: '1' }))
console.log(app.jwt.admin.sign({ sub: '2' }))
// TypeScript: ❌ Property 'auth' does not exist on type 'JWT'
// TypeScript: ❌ Property 'admin' does not exist on type 'JWT'
})
Expected behavior
fastify.jwt should be typed as { auth: JWT, admin: JWT } when using namespaces, or there should be a documented way (e.g. declaration merging) for users to override the type.
Context
The FastifyJwtNamespace type (line 48-73) correctly handles the request-level decorators (authJwtVerify, authJwtSign, etc.), but the fastify.jwt instance property has no corresponding namespace-aware typing.
Environment
@fastify/jwt: latest
- Node.js: 20+
- TypeScript: 5.x
Bug
When registering the plugin with
namespaceoption,fastify.jwtbecomes a{ [namespace]: JWT }map at runtime. However, TypeScript always types it asJWT(the single decorator shape).Current type declaration (
types/jwt.d.ts:16-18):Reproduction
Expected behavior
fastify.jwtshould be typed as{ auth: JWT, admin: JWT }when using namespaces, or there should be a documented way (e.g. declaration merging) for users to override the type.Context
The
FastifyJwtNamespacetype (line 48-73) correctly handles the request-level decorators (authJwtVerify,authJwtSign, etc.), but thefastify.jwtinstance property has no corresponding namespace-aware typing.Environment
@fastify/jwt: latest