#Delete
29 messages · Page 1 of 1 (latest)
There's not going to be any good way to do this directly ("union of every possible capitalization combination" is not good in my book). It may be possible with a validator pattern, but those are often not ergonomic.
Even if you get the types to work that just doesn't seem like a good idea.
Is the code consuming the headers going to have to separately check for x-custom-header, X-Custom-Header, X-custom-Header, x-custom-Header to see if the header is set?
If you're consuming headers from an external API, I would also standardize the capitalization when it comes in, if you're exposing the headers to the rest of the app in some type-aware way.
I don't think I understand what you mean.
Are these outgoing headers on requests you're sending out or inbound headers on requests coming in?
If those external APIs care about capitalization, then you'd want to type your version of the headers to match, right?
If the external APIs are inconsistent you'll have to fix the capitalization on a case-by-case basis before sending the request, I guess, but either way I'd keep the capitalization consistent within your system and deal with the inconsistency at the boundary.
I don't see why that would be the case.
If you're fixing the capitalization at the boundaries, then you can use a single standard representation in your system.
You don't generally want complexities of external systems to be reflected all throughout your system.
I would wrap that function in one that accepts headers, in my internal capitalization, and then fix the headers to be capitalized the way sendDataToEndpointX expects.
(Or probably, use my types for the external contract of that function and use the EXTERNAL_TYPES internal to the function to double-check)
Yeah, but I don't think making this case-insensitive at the type level actually solves anything, anyway.
// EndpointX requires a capitalized header
declare function sendDataToEndpointX(headers: { 'X-CUSTOM-HEADER': string }, data: string[]): void;
// representing the headers in a 'case-insenstive-way':
type MyHeadersType = {
[key in `${'x' | "X"}-CUSTOM-HEADER`]: string
}
declare const myHeaders: MyHeadersType;
// Can't actually prove this is formatted according to the capitalizaton endpointX requires, so this fails and we'd need a wrapping function anyway
sendDataToEndpointX(myHeaders, ["foo"]);
Odd, not sure why the bot isn't flagging an error on that last line,b ut it is in the playground like I'd expect:
Preview:```ts
declare function sendDataToEndpointX(
headers: {"X-CUSTOM-HEADER": string},
data: string[]
): void
type MyHeadersType = {
[key in ${"x" | "X"}-CUSTMO-HEADER]: string
}
declare const myHeaders: MyHeadersType
sendDataToEndpointX(myHeaders, ["foo"])```
what does import(EXTERNAL_TYPES) actually look like? if it contains specific header types you could presumably write a type to do this:
declare function sendDataToEndpointX(headers: SpecificRequestHeadersFrom<import(EXTERNAL_TYPES).SendDataToEndpointX>, data: unknown): import(EXTERNAL_TYPES).SendDataToEndpointX;
(and maybe the same for data too)
i generally agree with Retsam's perspective that you shouldn't let external details like this leak into your business logic
@vivid axle Here's a shortened URL of your playground link! You can remove the full link from your message.
Preview:```ts
declare function sendDataToEndpointX(
headers: {"X-CUSTOM-HEADER": string},
data: string[]
): void
type MyHeadersType = {
[key in ${"x" | "X"}-CUSTOM-HEADER]: string
}
declare const myHeaders: MyHeadersType
sendDataToEndpointX(myHeaders, ["foo"])```
try to actually set a value though:
Preview:ts ... const myHeaders: MyHeadersType = { "x-CUSTOM-HEADER": "blah", "X-CUSTOM-HEADER": "blah", } ...
presumably that is not what you want to make people do
the casing of object keys is included in the structure. if /example/x only accepts lowercase headers, that would be reflected in SpecificRequestHeadersFrom<import(EXTERNAL_TYPES).SendDataToEndpointX>
(if the the import(EXTERNAL_TYPES) type is correct to begin with)
can you share a specific example of the type that import(EXTERNAL_TYPES) resolves to?
Delete
!resolved