Skip to content

fix(types): stop LabelValues distributing over label-name unions - #862

Open
cpruijsen wants to merge 1 commit into
prometheus:mainfrom
cpruijsen:fix/issue-861
Open

cpruijsen wants to merge 1 commit into
prometheus:mainfrom
cpruijsen:fix/issue-861

Conversation

@cpruijsen

Copy link
Copy Markdown

Summary

Tuple-wrap both sides of the LabelValues check ([T] extends [NoLabelNameType]) so a multi-label get() keeps every declared key.

LabelValues<T> was a naked distributive conditional (T extends never). For a metric with two label names, LabelValues became a union of one-key objects, so const { values } = await counter.get(); values[0].labels.a failed to compile (TS2339) even though both keys were declared. The no-label never case resolves to Partial<Record<string, never>> (the empty-record type #655 intended; the naked form yielded never by distributing over the empty union).

test/typescript.ts reads .method and .status from a two-label Counter and Gauge get(). That access fails tsc on the old type.

Fixes #861.

Decision

Tuple-wrap both sides of the LabelValues check rather than revert to Partial<Record<T, string | number>> (prom-client 15.1.3). The tuple wrap is the form in the issue, and it keeps the no-label empty-record type from #655. Reverting would drop that branch.

Happy to switch if you would rather revert the alias, drop the changelog line, or also cover Histogram/Summary get() reads (same alias).

Test plan

  • npm run compile-typescript passes with the wrap.
  • Revert only the index.d.ts line; the new get() label reads fail tsc with TS2339 on the one-key union.
  • Restore the wrap; tsc is clean again.
  • npm run lint and npm run check-prettier pass.

A naked T extends never splits multi-label metrics into a union of
one-key objects, so reading labels back from get() keeps only one key.

Fixes prometheus#861

Signed-off-by: Christopher Pruijsen <christopher.pruijsen@gmail.com>

This branch has not been deployed

No deployments
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

Successfully merging this pull request may close these issues.

TypeScript: LabelValues distributes over label-name unions, so labels from get() lose all but one key

1 participant