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

types: HeadersInit does not accept arrays as values, but it will work #388

Closed
KianNH opened this issue Feb 17, 2023 · 6 comments
Closed
Assignees
Labels
types Related to @cloudflare/workers-types

Comments

@KianNH
Copy link
Contributor

KianNH commented Feb 17, 2023

HeadersInit is defined as type HeadersInit = Headers | Iterable<Iterable<string>> | Record<string, string> - the one that's of note is Record<string, string>.

The runtime will accept an array as the value for a given key, and fold them into a single header by joining them with a comma, but the types don't allow this.

image

image

I assume it's defined here, and should instead be Record<string, string | string[]>.

JSG_TS_DEFINE(type HeadersInit = Headers | Iterable<Iterable<string>> | Record<string, string>);

@KianNH KianNH added the types Related to @cloudflare/workers-types label Feb 17, 2023
@KianNH
Copy link
Contributor Author

KianNH commented Feb 17, 2023

Iterable<Iterable<string>> would also need updating to Iterable<Iterable<string | string[]>> to support this - but there seems to be another issue with that type.

It'll accept [ 'lol', 'bar', 'lol2', 'bar2' ] which is then rejected at runtime: TypeError: Incorrect type: the provided value is not of type 'Sequence'.

@KianNH
Copy link
Contributor Author

KianNH commented Feb 17, 2023

I guess another viewpoint is, should it accept an array of values?

https://fetch.spec.whatwg.org/#headers-class appears to say no.

@kentonv
Copy link
Member

kentonv commented Feb 17, 2023

The runtime is not intentionally designed to allow an array here. The reason it works is because of the general JavaScript behavior of being able to coerce anything to a string. ["foo","bar"].toString() is foo,bar. This just happens to be the correct way to combine multiple header values under HTTP, but this is entirely an unintended coincidence.

@KianNH
Copy link
Contributor Author

KianNH commented Feb 17, 2023

Thanks for the insight Kenton, that makes sense.

The issue is actually off the back of what Undici (through Miniflare) does - where they allow arrays as values, especially for setting multiple Set-Cookie headers. It got me curious as to what the behaviour should be as per the spec.

Someone reported this discrepancy on the Wrangler repo: cloudflare/workers-sdk#2743

The change in Undici is nodejs/undici#1598, but I can't really find anything to back that up as something that is supposed to be possible under the Fetch spec - it's also possible that change isn't strictly what causes the behaviour since they also have some set-cookie specific handling in general.

@mrbbot
Copy link
Contributor

mrbbot commented Mar 6, 2023

Hey! 👋 I think we should keep these types the same for now, considering this is what TypeScript's lib.webworker.d.ts looks like (https://github.com/microsoft/TypeScript/blob/43cc362cef72e5fa1372f59736a9c4b55d85def0/lib/lib.webworker.d.ts#L6110) and #321 didn't change the constructor implementation/types. It seems like the correct way of specifying multiple Set-Cookie headers is via an array of key-value pairs? The existing types should support this. 👍

@mrbbot mrbbot closed this as completed Mar 6, 2023
@KianNH
Copy link
Contributor Author

KianNH commented Mar 6, 2023

It seems like the correct way of specifying multiple Set-Cookie headers is via an array of key-value pairs? The existing types should support this. 👍

This makes sense, but the current workers-types uses Iterable<Iterable<string> which does not line up with the lib.webworker.d.ts types.

Whilst both will accept [ ['Set-Cookie', 'sessionId=38afes7a8'], ['Set-Cookie', 'sessionId=38afes7a9'] ] which is correct, Iterable<Iterable<string> will accept ['foo', 'bar'] and you will hit a runtime error like described here: #388 (comment)

image

Shouldn't the workers-types be changed to match the lib.webworker.d.ts types exactly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types Related to @cloudflare/workers-types
Projects
Archived in project
Development

No branches or pull requests

4 participants