elysia
elysia copied to clipboard
Types for JWT plugin are not propagated correctly
It seems my jwtFunc
is correctly propagated only to directly chained request handlers, not to plugins or functional callbacks. Is this issue or there is another way how to have correct typing if handlers are in separe files?
const JWTMiddleware = jwt({
name: 'jwtFunc',
secret: 'password',
})
/*
* Property 'jwtFunc' does not exist on type '{ body: unknown; query: Record<string, string | null>; params: Record<"name",
* string>; headers: Record<string, string | null>; cookie: Record<string, Cookie<any>>; set: { ...; }; path: string; request:
* Request; store: {}; }'.
*/
const plugin = new Elysia().get('/sign/:name', ({ jwtFunc, params }) =>
jwtFunc.sign(params)
)
/*
* Property 'jwtFunc' does not exist on type '{ body: unknown; query: Record<string, string | null>; params: Record<"name",
* string>; headers: Record<string, string | null>; cookie: Record<string, Cookie<any>>; set: { ...; }; path: string; request:
* Request; store: {}; }'.
*/
export const functionalCallback = (app: Elysia) =>
app.get('/sign/:name', ({ jwtFunc, params }) => jwtFunc.sign(params))
const app = new Elysia()
.use(JWTMiddleware)
.use(cookie())
.use(swagger())
.use(plugin)
.use(functionalCallback)
.get('/sign/:name', ({ jwtFunc, params }) => jwtFunc.sign(params)) // this is OK
I'm also getting the same error
I got the same issue.
Same issue here, the example actually raises a TS error on 'jwt' at .get('/sign/:name', async ({ jwt, cookie, setCookie, params }) =>
any updates on this yet guys?
I think this might be what you're looking for, Dependency Injection
A temporary fix is to downgrade Elysia to 0.7.15, seems it got broken in 0.7.16
"dependencies": {
"@elysiajs/cookie": "^0.7.0",
"@elysiajs/jwt": "^0.7.0",
"elysia": "0.7.15"
}
This works for me
Same as well with me. Help Salty!!!
It happens to me too but I get why its hard to infer:
You create detached middlewares/plugins/derivations(decide on the name already lol) but the plugin itself is registered on some root app instance.
So the root app is quite aware of the plugins it passes to its context, however, the standalone functions aren't because there's no guarantee for them to be executed in this context, or at least - there's no way to type this kind of guaranty AFAIK.
This is because the way that Elysia builds type. I had this problem too. The way that i found to fix that is using one root app and set all my functionalities there and export the type of the app, like this:
// server.ts
export const app = new Elysia({ cookie: { secrets: Bun.env.JWT_SECRET } })
.use(
jwt({
name: 'jwt',
secret: Bun.env.JWT_SECRET || 'super_secret',
exp: '2d',
})
);
export type AppType = typeof app;
And in other files, you could use the exported type to type the new Elysia object:
import { AppType } from '@server';
import Elysia from 'elysia';
const plugin: AppType = new Elysia();
plugin.get('/sign/:name', ({ jwt, params }) => jwt.sign(params)); // <-- No type errors here + all infered type features
update elysia ^0.7.0 -> ^0.8.0.
It seems my
jwtFunc
is correctly propagated only to directly chained request handlers, not to plugins or functional callbacks. Is this issue or there is another way how to have correct typing if handlers are in separe files?const JWTMiddleware = jwt({ name: 'jwtFunc', secret: 'password', }) /* * Property 'jwtFunc' does not exist on type '{ body: unknown; query: Record<string, string | null>; params: Record<"name", * string>; headers: Record<string, string | null>; cookie: Record<string, Cookie<any>>; set: { ...; }; path: string; request: * Request; store: {}; }'. */ const plugin = new Elysia().get('/sign/:name', ({ jwtFunc, params }) => jwtFunc.sign(params) ) /* * Property 'jwtFunc' does not exist on type '{ body: unknown; query: Record<string, string | null>; params: Record<"name", * string>; headers: Record<string, string | null>; cookie: Record<string, Cookie<any>>; set: { ...; }; path: string; request: * Request; store: {}; }'. */ export const functionalCallback = (app: Elysia) => app.get('/sign/:name', ({ jwtFunc, params }) => jwtFunc.sign(params)) const app = new Elysia() .use(JWTMiddleware) .use(cookie()) .use(swagger()) .use(plugin) .use(functionalCallback) .get('/sign/:name', ({ jwtFunc, params }) => jwtFunc.sign(params)) // this is OK
See example in Documentation - Plugin#service-locator
It seems my
jwtFunc
is correctly propagated only to directly chained request handlers, not to plugins or functional callbacks. Is this issue or there is another way how to have correct typing if handlers are in separe files?const JWTMiddleware = jwt({ name: 'jwtFunc', secret: 'password', }) /* * Property 'jwtFunc' does not exist on type '{ body: unknown; query: Record<string, string | null>; params: Record<"name", * string>; headers: Record<string, string | null>; cookie: Record<string, Cookie<any>>; set: { ...; }; path: string; request: * Request; store: {}; }'. */ const plugin = new Elysia().get('/sign/:name', ({ jwtFunc, params }) => jwtFunc.sign(params) ) /* * Property 'jwtFunc' does not exist on type '{ body: unknown; query: Record<string, string | null>; params: Record<"name", * string>; headers: Record<string, string | null>; cookie: Record<string, Cookie<any>>; set: { ...; }; path: string; request: * Request; store: {}; }'. */ export const functionalCallback = (app: Elysia) => app.get('/sign/:name', ({ jwtFunc, params }) => jwtFunc.sign(params)) const app = new Elysia() .use(JWTMiddleware) .use(cookie()) .use(swagger()) .use(plugin) .use(functionalCallback) .get('/sign/:name', ({ jwtFunc, params }) => jwtFunc.sign(params)) // this is OK
See example in Documentation - Plugin#service-locator
Close as unable to reproduce on my end, either it was fixed in previous subsequent version and service locator pattern.
Feels free to open a new issue referencing this one if the problem still persists.