Skip to content
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

How to return Node.js Buffer with TypeScript 5.7? #3720

Open
yusukebe opened this issue Dec 4, 2024 Discussed in #3700 · 1 comment
Open

How to return Node.js Buffer with TypeScript 5.7? #3720

yusukebe opened this issue Dec 4, 2024 Discussed in #3700 · 1 comment

Comments

@yusukebe
Copy link
Member

yusukebe commented Dec 4, 2024

Discussed in https://github.com/orgs/honojs/discussions/3700

Originally posted by marvinruder November 24, 2024
The code

import { serve } from '@hono/node-server'
import { Hono } from 'hono'
import { etag } from 'hono/etag'

const app = new Hono()
app.use(etag())
app.get('/', (c) => c.body(Buffer.from('Hello Hono!')))
serve({ fetch: app.fetch })

runs as expected and shows no errors in TypeScript 5.6, but the following error is shown with TypeScript 5.7:

No overload matches this call.
  Overload 1 of 2, '(data: Data | null, status?: StatusCode | undefined, headers?: HeaderRecord | undefined): Response', gave the following error.
    Argument of type 'Buffer<ArrayBuffer>' is not assignable to parameter of type 'Data | null'.
      Type 'Buffer<ArrayBuffer>' is missing the following properties from type 'ArrayBuffer': maxByteLength, resizable, resize, detached, and 2 more.
  Overload 2 of 2, '(data: Data | null, init?: ResponseInit | undefined): Response', gave the following error.
    Argument of type 'Buffer<ArrayBuffer>' is not assignable to parameter of type 'Data | null'.
      Type 'Buffer<ArrayBuffer>' is missing the following properties from type 'ArrayBuffer': maxByteLength, resizable, resize, detached, and 2 more.

This is because a Buffer is no longer an ArrayBuffer (see https://devblogs.microsoft.com/typescript/announcing-typescript-5-7/#typedarrays-are-now-generic-over-arraybufferlike, microsoft/TypeScript#59417 for details), and the Data type can only be a string, ArrayBuffer, or ReadableStream.

Returning the ArrayBuffer within the Buffer using

app.get('/', (c) => c.body(Buffer.from('Hello Hono!').buffer))

shows no type error, but leads to unexpected results, as responses are 8192 bytes long and contain lots of unrelated data. The reason for this is the shared memory pool from the Buffer module:

The Buffer module pre-allocates an internal Buffer instance of size Buffer.poolSize that is used as a pool for the fast allocation of new Buffer instances created using Buffer.allocUnsafe(), Buffer.from(array), Buffer.from(string), and Buffer.concat() only when size is less than Buffer.poolSize >>> 1 (floor of Buffer.poolSize divided by two). (https://nodejs.org/api/buffer.html#static-method-bufferallocunsafesize)

What is the recommended way to use a Node.js Buffer as the body of a response? Do Hono’s types need to be updated to conform with the changes in TypeScript 5.7?

@marvinruder
Copy link

Related: #3729

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants