diff --git a/CHANGELOG.md b/CHANGELOG.md index 11be4a31..4507479f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ This release marks our first release under the Prometheus umbrella. - Metric internal storage ('hashMap') changed to a separate object, LabelMap. If you have subclassed the built-in metric types you may need to adjust your code. - Counter Exemplars now report the value rather than the delta +- TypeScript: `MetricType` is now a string union matching the runtime values + (`'counter' | 'gauge' | 'histogram' | 'summary'`) instead of a numeric enum that had no + runtime object. Value-style uses such as `MetricType.Counter` (which threw at runtime) + no longer compile; compare against the string literals instead. Under + `verbatimModuleSyntax`, import it with `import type`. ### Changed diff --git a/index.d.ts b/index.d.ts index 5b1a81d4..37b91973 100644 --- a/index.d.ts +++ b/index.d.ts @@ -270,12 +270,11 @@ export type Metric = */ export type Aggregator = 'omit' | 'sum' | 'first' | 'min' | 'max' | 'average'; -export enum MetricType { - Counter, - Gauge, - Histogram, - Summary, -} +/** + * The metric type reported in metric objects, such as those returned by + * `Registry#getMetricsAsJSON()`. Matches the runtime string values. + */ +export type MetricType = 'counter' | 'gauge' | 'histogram' | 'summary'; type CollectFunction = (this: T) => void | Promise; diff --git a/test/typescript.ts b/test/typescript.ts index 36900684..f55a15f4 100644 --- a/test/typescript.ts +++ b/test/typescript.ts @@ -18,6 +18,7 @@ import { Registry, MetricObject, MetricObjectWithValues, + MetricType, MetricValue, MetricValueWithName, } from '../index'; @@ -71,3 +72,38 @@ async function metricObjectTypesAreExported() { void named; } void metricObjectTypesAreExported; + +// MetricType matches the runtime strings reported in metric metadata, so a +// reported type can be compared against a literal and narrowed without casts. +// The switch fails to compile if the union and this member list ever drift +// apart, in either direction. +async function metricTypeMatchesRuntimeStrings() { + const t: MetricType = 'counter'; + void t; + + const [first] = await registry.getMetricsAsJSON(); + if (first !== undefined && first.type === 'counter') { + const narrowed: 'counter' = first.type; + void narrowed; + } + + const lockMembers = (type: MetricType): string => { + switch (type) { + case 'counter': + case 'gauge': + case 'histogram': + case 'summary': + return type; + default: { + const missing: never = type; + return missing; + } + } + }; + void lockMembers; + + // @ts-expect-error MetricType is a type-only string union with no runtime + // object (#336), so value-style access must not compile. + void MetricType.Counter; +} +void metricTypeMatchesRuntimeStrings;