Summary
src/tracing_channels.ts passes the channel name as the first type
argument to diagnostics_channel.tracingChannel:
// src/tracing_channels.ts
export const dispatchChannel = diagnostics_channel.tracingChannel<
'boringqueue.job.dispatch',
JobDispatchMessage
>('boringqueue.job.dispatch')
export const executeChannel = diagnostics_channel.tracingChannel<
'boringqueue.job.execute',
JobExecuteMessage
>('boringqueue.job.execute')
That matched @types/node v25, where the first parameter was the unconstrained
StoreType. In @types/node v26 the two parameters were swapped and the
first one is now constrained to object, so a string literal no longer fits:
// @types/node@25.9.4 — diagnostics_channel.d.ts
function tracingChannel<
StoreType = unknown,
ContextType extends object = StoreType extends object ? StoreType : object,
>(nameOrChannels: string | TracingChannelCollection<StoreType, ContextType>)
// @types/node@26.3.0 — diagnostics_channel.d.ts
function tracingChannel<ContextType extends object = object, StoreType = ContextType>(
nameOrChannels: string | TracingChannelCollection<ContextType, StoreType>,
): TracingChannel<ContextType, StoreType>
The result is that the published declarations of @boringnode/queue do not
compile for any consumer on @types/node v26 or later. The repository does not
see it because devDependencies pins @types/node@^25.9.4, which cannot
resolve to v26.
Reproduction
mkdir repro && cd repro
npm init -y && npm pkg set type=module
npm i @boringnode/queue
npm i -D typescript@7.0.2 @types/node@26.3.0 knex@3.1.0
cat > tsconfig.json <<'JSON'
{
"compilerOptions": {
"target": "esnext",
"module": "preserve",
"moduleResolution": "bundler",
"types": ["node"],
"strict": true,
"skipLibCheck": false,
"noEmit": true
}
}
JSON
printf 'import { Job } from "@boringnode/queue"\nexport const j = Job\n' > index.ts
npx tsc --noEmit
Result:
node_modules/@boringnode/queue/build/index.d.ts(600,67): error TS2344:
Type 'string' does not satisfy the constraint 'object'.
node_modules/@boringnode/queue/build/index.d.ts(605,66): error TS2344:
Type 'string' does not satisfy the constraint 'object'.
(knex is installed here only to isolate this issue from the separate root
barrel leak reported alongside it.)
Proposed fix
Drop the name type argument. The channel name is a runtime value, and in both
signatures the message type is happy as the sole argument:
- export const dispatchChannel = diagnostics_channel.tracingChannel<
- 'boringqueue.job.dispatch',
- JobDispatchMessage
- >('boringqueue.job.dispatch')
+ export const dispatchChannel =
+ diagnostics_channel.tracingChannel<JobDispatchMessage>('boringqueue.job.dispatch')
- export const executeChannel = diagnostics_channel.tracingChannel<
- 'boringqueue.job.execute',
- JobExecuteMessage
- >('boringqueue.job.execute')
+ export const executeChannel =
+ diagnostics_channel.tracingChannel<JobExecuteMessage>('boringqueue.job.execute')
I checked this compiles on both major versions, so it needs no @types/node
bump and breaks nothing for existing users:
| Form |
@types/node@25.9.4 |
@types/node@26.3.0 |
| current — <'boringqueue.job.dispatch', JobDispatchMessage> |
passes |
TS2344 |
| proposed — <JobDispatchMessage> |
passes |
passes |
On v25 the sole argument binds to StoreType, and ContextType defaults to
StoreType extends object ? StoreType : object, which resolves to the message
type. On v26 it binds to ContextType, and StoreType defaults to it. Both
end up with the same pair.
Widening the @types/node dev dependency to ^25.9.4 || ^26.0.0 would keep
this from regressing.
Happy to send a PR
Small change, and I have both matrices reproduced locally.
Related reports opened at the same time: #24 (root barrel re-exporting the Knex-only QueueSchemaService) and #26 (./types re-exporting an OpenTelemetry type). Independent of each other.
Summary
src/tracing_channels.ts passes the channel name as the first type
argument to diagnostics_channel.tracingChannel:
That matched @types/node v25, where the first parameter was the unconstrained
StoreType. In @types/node v26 the two parameters were swapped and the
first one is now constrained to object, so a string literal no longer fits:
The result is that the published declarations of @boringnode/queue do not
compile for any consumer on @types/node v26 or later. The repository does not
see it because devDependencies pins @types/node@^25.9.4, which cannot
resolve to v26.
Reproduction
Result:
(knex is installed here only to isolate this issue from the separate root
barrel leak reported alongside it.)
Proposed fix
Drop the name type argument. The channel name is a runtime value, and in both
signatures the message type is happy as the sole argument:
I checked this compiles on both major versions, so it needs no @types/node
bump and breaks nothing for existing users:
On v25 the sole argument binds to StoreType, and ContextType defaults to
StoreType extends object ? StoreType : object, which resolves to the message
type. On v26 it binds to ContextType, and StoreType defaults to it. Both
end up with the same pair.
Widening the @types/node dev dependency to ^25.9.4 || ^26.0.0 would keep
this from regressing.
Happy to send a PR
Small change, and I have both matrices reproduced locally.
Related reports opened at the same time: #24 (root barrel re-exporting the Knex-only QueueSchemaService) and #26 (./types re-exporting an OpenTelemetry type). Independent of each other.