Pass a string field to c.json throws Type instantiation is excessively deep and possibly infinite.ts(2589)
What version of Hono are you using?
4.6.3
What runtime/platform is your app running on?
Node
What steps can reproduce the bug?
- Return a c.json with a string field
- Let it empty or add a . or /
What is the expected behavior?
No typescript errors
What do you see instead?
Type instantiation is excessively deep and possibly infinite.ts(2589)
Additional information
If you add another character this error does not happen or if you delete the period.
typescript: ^5.6.2
This seems to be due to the complex computed types in src/utils/types.ts. I would imagine that breaking these down into smaller definitions will help (based on this issue).
Something like this maybe? Happy to create a PR if this looks good maintainers.
// Intermediate types to simplify JSONParsed
type ToJSON<T> = T extends { toJSON(): infer J } ? J : never
type HandleInvalidJSON<T> = T extends InvalidJSONValue ? never : T
type HandleArray<T> = T extends ReadonlyArray<unknown>
? { [K in keyof T]: JSONParsed<InvalidToNull<T[K]>> }
: T
type HandleSetMap<T> = T extends Set<unknown> | Map<unknown, unknown> ? {} : T
type HandleObject<T> = T extends object
? {
[K in keyof OmitSymbolKeys<T> as IsInvalid<T[K]> extends true
? never
: K]: boolean extends IsInvalid<T[K]> ? JSONParsed<T[K]> | undefined : JSONParsed<T[K]>
}
: T
// Simplified JSONParsed type
export type JSONParsed<T> = T extends JSONPrimitive
? T
: ToJSON<T> extends never
? HandleInvalidJSON<HandleArray<HandleSetMap<HandleObject<T>>>>
: JSONParsed<ToJSON<T>>
Hi @kaio-eduardo
I can't reproduce it. Can you provide a minimal project to reproduce it?
@yusukebe it can be reproduced by passing unknown to c.json
minimal reproduction:
import { Hono } from "jsr:@hono/hono@^4.6.11"
new Hono().get("/", (c) => c.json({} as unknown))
jsr:@hono/hono@^4.6.11
deno 2.1.2 (stable, release, aarch64-apple-darwin)
v8 13.0.245.12-rusty
typescript 5.6.2
@scarf005
Why do you need to add unknown? I can't help you if you want to add unknown.
Why do you need to add
unknown? I can't help you if you want to addunknown.
I want to return JSON file and not have type is excessively deep errors.
@scarf005
Sorry. I can't understand it. If you want our help, please provide a minimal project to reproduce it and show an interaction.
Sorry. I can't understand it. If you want our help, please provide a minimal project to reproduce it and show an interaction.
import { Hono } from "jsr:@hono/hono@^4.6.11"
new Hono().get("/", async (c) => c.json(JSON.parse(await Deno.readTextFile("file.json")) as unknown))
sorry, i don't understand which part you don't understand. could you elaborate?
@scarf005
You can't use unknown. To prevent the type error, please use as any.
The same error occurs when trying to reference ReturnType of c.json.
reproduction: https://stackblitz.com/edit/github-a8gzkzvs
import { serve } from '@hono/node-server';
import { Hono, type Context } from 'hono';
import { createMiddleware } from 'hono/factory';
interface Env {
Variables: {
echo: (data: string) => ReturnType<Context['json']>;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Type instantiation is excessively deep and possibly infinite.(2589)
};
}
const echoMiddleware = createMiddleware<Env>(async (c, next) => {
c.set('echo', (data) => c.json({ data }));
await next();
});
const app = new Hono();
app.get('/', echoMiddleware, (c) => {
return c.var.echo('Hello Hono!');
});
const port = 3000;
console.log(`Server is running on http://localhost:${port}`);
serve({
fetch: app.fetch,
port,
});
Hi @ghaaj You can use this
interface Env {
Variables: {
echo: (data: string) => Response;
};
}
The reason for that error, c.json contains the types of Variables
@EdamAme-x
Thank you! I'm thinking of using Response & TypedResponse<...> for more type safety.
I am sorry for the extra notifications.
Hmmm, I don't think that way would change the type safety.
This issue has been marked as stale due to inactivity.
Closing this issue due to inactivity.