-
-
Notifications
You must be signed in to change notification settings - Fork 615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug: JSONParsed type not correctly working for generic type #3135
Comments
@MathurAditya724 Thank you for the issue. @m-shaka Can you take a look at it? |
Ok! |
@m-shaka Thank you for the PR! @MathurAditya724 I'm sure regression occurred, but I don't know if we can say it's a real bug since it is not expected for such complex usage. I'll look into it too. |
Thank you, @yusukebe and @m-shaka, for taking the time to address this issue. This is particularly relevant for those of us building custom middleware wrappers and libraries around Hono. Utilizing generic types is quite common, and I’ve encountered similar challenges while working on Honohub during the upgrade to the newer version. You are correct that this seems more like a feature/improvement rather than a bug. |
Hi @MathurAditya724 cc: @m-shaka I've struggled to resolve this issue today, but I can't find a good way to remove the error. And #3138 by @m-shaka may not be the correct solution. Handling
|
Hmm. Anyway, I also think supporting it would be great. |
@NamesMT Hey. Do you have any thoughts? |
This is a little bit tricky, but you can get import { Context } from "hono";
import { StatusCode } from "hono/utils/http-status";
const contextVariables = {};
function okTypeHelper(c: Context) {
return <TData>(data: TData, meta?: { count?: number }) => c.json( { data, meta } );
}
type Ok = ReturnType<typeof okTypeHelper>
export type PublicContextVariables = typeof contextVariables & {
ok: Ok
}; It seems like I got a strict response type on #3138 |
After some hours of testing, I've come with a conclusion: If you get the This is my minimal re-produce example, note that I have assigned a default value for export type PublicContextVariables = {
ok: <TData extends number = 3>(data: TData) => TData
};
new Hono<{ Variables: PublicContextVariables }>()
.use((ctx, next) => {
ctx.set('ok', (data) => {
// data is hinted as `TData extends number = 3`
// DataType is hinted as `TData`
type DataType = typeof data
type CheckIsAny = Expect<Equal<IsAny<DataType>, true>> // Type 'boolean' is not assignable to type 'true'
type CheckIsUnknown = Expect<DataType extends unknown ? true : false> // Type 'boolean' is not assignable to type 'true'
return data
})
return next()
}) I think this is because, as you can see, the signature of The weird/buggy part is that TypeScript sets the |
If my previous comment is correct, this is not really an issue with #3074, IMO #3074 should be kept as it is a good improvement overall for |
I agree with @NamesMT, that we should keep the functionality introduced in #3074. For the generics, IMHO it's not that TypeScript sets the It would be better to have a hybrid approach to resolve this issue. So to put this into perspective, this is what was happening in Both static and generic types can return functions. Now in the current version Static types are improved but generic types are having issues. So I think the best approach will be to parse the static types and leave the generic ones that I believe @m-shaka has already achieved in #3138. But I do find it weird that we cannot extend the generic type - |
On second thought, if we can figure out why we are unable to extend the generic type we can solve this. Then the dev can just extend it to be of type
|
Let me summarise the discussion so far. First, the concern @yusukebe described is about the difference between Second, I guess @NamesMT pointed out the exact cause of this regression! Thank you. I think I could solve that on #3138 to some extent without giving up the strict JSON typing as @MathurAditya724 mentioned, and also I found a way to use import { Context, Hono } from "hono";
import { serve } from "@hono/node-server";
const contextVariables = {};
const ERROR_RESPONSES = {
NOT_FOUND: { message: "Not found", code: 404 },
INTERNAL: { message: "Not found", code: 500 },
} as const;
type ErrorName = keyof typeof ERROR_RESPONSES;
function okHelper(ctx: Context) {
return <TData>(data: TData, meta?: { count?: number }) => ctx.json( { data, meta } );
}
function failHelper(ctx: Context) {
return (errorName: ErrorName) =>
ctx.json({ error: ERROR_RESPONSES[errorName] }, ERROR_RESPONSES[errorName].code);
}
function okExtendedHelper(ctx: Context) {
return <TData extends number>(data: TData, meta?: { count?: number }) => ctx.json( { data, meta } );
}
type Ok = ReturnType<typeof okHelper>
type Fail = ReturnType<typeof failHelper>
type OkExtended = ReturnType<typeof okExtendedHelper>
export type PublicContextVariables = typeof contextVariables & {
ok: Ok
fail: Fail
okExtended: OkExtended
};
const app = new Hono<{ Variables: PublicContextVariables }>();
const routes = app
.use((ctx, next) => {
Object.entries(contextVariables).forEach(([name, value]) => {
ctx.set(name as never, value as never);
});
// works on main
ctx.set("ok", okHelper(ctx));
ctx.set("fail", failHelper(ctx));
ctx.set("okExtended", okExtendedHelper(ctx));
// doesn't work on main, but works on #3138
ctx.set("ok", (data, meta) => ctx.json({ data, meta }));
// doesn't work anywhere for now
// @ts-expect-error
ctx.set("okExtended", (data, meta) => ctx.json({ data, meta }));
return next();
})
.get("/ping", ({ var: { ok, okExtended } }) =>{
return ok(['ping', undefined] as const, { count: 2 })
}
)
.get("/extended", ({ var: { okExtended } }) => {
// @ts-expect-error
okExtended('foo')
return okExtended(1)
})
serve({
fetch: app.fetch,
port: 4000,
}); Does it make sense? |
The things that @m-shaka summarised sound good. I think this @MathurAditya724 's issue will be fixed by #3138. I'll merge it into |
@MathurAditya724 FYI ctx.set("ok", (data, meta) => ctx.json({ data, meta })); See #3310 |
Oh God! I need to update my libs now 🥲. Thanks for the heads-up |
What version of Hono are you using?
4.4.13
What runtime/platform is your app running on?
Nodejs
What steps can reproduce the bug?
This is happening in the last 2 releases,
v4.4.12
andv4.4.13
. It seems like the issue is occurring because of this #3074 PR. A community member has created a sample repo - https://github.com/avetisk/dummy-hono-context-helper-type/blob/main/serve.tsThe issue is with the generic type (
TData
in this case), if we remove the generic type everything works like normal.I believe it is occurring because of this new addition in the
JSONParsed
type -Even if we
extend
the type, it still gives the error.What is the expected behavior?
No response
What do you see instead?
No response
Additional information
No response
The text was updated successfully, but these errors were encountered: