#Delete

29 messages · Page 1 of 1 (latest)

devout spoke
#

Personally, I would just have my API expect a specific capitalization and update code to match it if necessary.

#

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.

wind tartanBOT
#
// 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"]);
devout spoke
#

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:

wind tartanBOT
#
retsam19#0

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"])```

unkempt lynx
#

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

wind tartanBOT
#

@vivid axle Here's a shortened URL of your playground link! You can remove the full link from your message.

mlocik97#0

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"])```

unkempt lynx
#

try to actually set a value though:

wind tartanBOT
#
mkantor#0

Preview:ts ... const myHeaders: MyHeadersType = { "x-CUSTOM-HEADER": "blah", "X-CUSTOM-HEADER": "blah", } ...

unkempt lynx
#

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?

vivid axle
#

Delete

devout spoke
#

!resolved