diff --git a/src/wasm/stream.ts b/src/wasm/stream.ts index 694820c..3b35d13 100644 --- a/src/wasm/stream.ts +++ b/src/wasm/stream.ts @@ -5,6 +5,7 @@ * Use `.pipeThrough()` instead of `.pipe()`. */ +import type { Transformer } from 'node:stream/web'; import { createLZMAError } from '../errors.js'; import type { LZMAOptions } from '../types.js'; import { code, decoderInit, encoderInit, end, getModule } from './bindings.js'; @@ -65,9 +66,13 @@ export function createXz(opts?: LZMAOptions): TransformStream & { + cancel?: (reason: unknown) => void | PromiseLike; }); } @@ -125,9 +130,10 @@ export function createUnxz(): TransformStream { } }, /* cancel() frees WASM resources when the readable side is cancelled. - Part of the Streams spec but not yet in TypeScript's DOM lib. */ - // @ts-expect-error cancel is a valid Transformer method per Streams spec + See createXz() for the rationale on the intersection cast. */ cancel: doCleanup, + } as Transformer & { + cancel?: (reason: unknown) => void | PromiseLike; }); } diff --git a/test/wasm/stream-directive-hygiene.test.ts b/test/wasm/stream-directive-hygiene.test.ts new file mode 100644 index 0000000..6ae761b --- /dev/null +++ b/test/wasm/stream-directive-hygiene.test.ts @@ -0,0 +1,29 @@ +import { readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; + +/** + * Forward-compat guard for `src/wasm/stream.ts`. + * + * `@types/node` adds and (more rarely) removes typed members of the Streams + * interfaces across minor bumps. The file deliberately uses an intersection + * cast on `TransformStream` constructor calls so it needs ZERO TypeScript + * suppression directives. Any directive — in either the expect-error or + * ignore form — would either mask a real upstream regression, or fire + * TS2578 ("unused directive") the moment the typing it suppresses lands + * upstream, breaking the daily Refresh Lockfile workflow. + * + * This test is the deterministic regression detector for that invariant. + */ +describe('src/wasm/stream.ts — TS directive hygiene', () => { + it('contains no @ts-ignore or @ts-expect-error directive', () => { + const path = fileURLToPath(new URL('../../src/wasm/stream.ts', import.meta.url)); + const source = readFileSync(path, 'utf8'); + + // Match the directive form specifically (with leading `//` and a word boundary + // after the directive name), so the rule name appearing inside a doc-comment + // or string literal does not produce a false positive. + const directivePattern = /\/\/\s*@ts-(expect-error|ignore)\b/; + expect(source).not.toMatch(directivePattern); + }); +});