Skip to content

Conversation

@Touffy
Copy link
Contributor

@Touffy Touffy commented Nov 24, 2025

This very simple PR adds a type parameter to all three negotiation functions (accepts, acceptsEncoding, acceptsLanguage) when they are called with more than one argument, so that the returned string will have the same specific type as the provided values.

This typing better reflects the actual behaviour (providing those arguments ensures that the returned value will be one of them, if any was acceptable) and improves type checking down the line when the content-types, encodings, or language code are used as keys (which is quite often, in my experience).

For example:

import { accepts } from "jsr:@std/[email protected]/negotiation"

const serializers = {
  "text/csv"() { return new TransformStream(/*...*/) },
  "application/x-ndjson"() { return new TransformStream(/*...*/) },
} satisfies Record<string, () => TransformStream<MyData, Uint8Array>>

type SupportedContentType = keyof typeof serializers

/* handling some request... */
Deno.serve((req) => {
  // currently, this is a string | undefined, but should be a SupportedContentType | undefined
  const acceptable = accepts(req, ...Object.keys(serializers))
  if (!acceptable) return new Response("Not Acceptable", {status: 406})

  const myData: ReadableStream<MyData> = getMyData()
  // because acceptable is a generic string, TypeScript doesn't trust it to access one of the serializers
  return new Response(myData.pipeThrough(serializers[acceptable]()))
})

@Touffy Touffy requested a review from kt3k as a code owner November 24, 2025 10:28
@CLAassistant
Copy link

CLAassistant commented Nov 24, 2025

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions bot added the http label Nov 24, 2025
@codecov
Copy link

codecov bot commented Nov 24, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.11%. Comparing base (798fd7b) to head (3738b38).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6876   +/-   ##
=======================================
  Coverage   94.10%   94.11%           
=======================================
  Files         581      581           
  Lines       42699    42699           
  Branches     6790     6790           
=======================================
+ Hits        40182    40185    +3     
+ Misses       2466     2463    -3     
  Partials       51       51           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Touffy Touffy changed the title typing(http): negotiation returns the specific type of supported outcomes (when provided) docs(http): negotiation returns the specific type of supported outcomes (when provided) Nov 24, 2025
Copy link
Member

@kt3k kt3k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Let's try this! LGTM

@kt3k kt3k changed the title docs(http): negotiation returns the specific type of supported outcomes (when provided) fix(http): negotiation returns the specific type of supported outcomes (when provided) Nov 26, 2025
@kt3k kt3k merged commit 80066bb into denoland:main Nov 26, 2025
23 of 24 checks passed
@Touffy Touffy deleted the negotiation-typing branch November 30, 2025 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants