From 10a64c677dbad5d01d55ee9245c32ca3aa7cf8b9 Mon Sep 17 00:00:00 2001 From: Tom Quist Date: Mon, 23 Mar 2026 13:28:58 +0100 Subject: [PATCH 1/4] fix(types): use .js extension in fxp.d.ts for NodeNext (TS2834) Relative imports in declaration files must use explicit .js extensions when consumers use moduleResolution node16/nodenext with skipLibCheck false. Fixes #808 --- src/fxp.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fxp.d.ts b/src/fxp.d.ts index 05e38de7..84199a16 100644 --- a/src/fxp.d.ts +++ b/src/fxp.d.ts @@ -1,4 +1,4 @@ -import type { Expression, ReadonlyMatcher } from './pem'; +import type { Expression, ReadonlyMatcher } from './pem.js'; // jPath: true → string // jPath: false → ReadonlyMatcher From 38c7eff1762bd29d98e489266c8b277f3a448000 Mon Sep 17 00:00:00 2001 From: Tom Quist Date: Mon, 23 Mar 2026 13:30:06 +0100 Subject: [PATCH 2/4] fix(types): NodeNext-safe relative import in fxp.d.ts Use ./pem.js in the ESM declaration so TypeScript with moduleResolution node16/nodenext and skipLibCheck false does not report TS2834. Adds test-types-nodenext and a CI step to guard against regression. Fixes #808 --- .github/workflows/node.js.yml | 1 + package.json | 1 + spec/typings/nodenext-import-test.ts | 10 ++++++++++ spec/typings/tsconfig.nodenext.json | 11 +++++++++++ 4 files changed, 23 insertions(+) create mode 100644 spec/typings/nodenext-import-test.ts create mode 100644 spec/typings/tsconfig.nodenext.json diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 2be0a8e5..2fd1cb7c 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -27,6 +27,7 @@ jobs: run: echo "PUBLISH_PLEASE_DISABLE_PROMPT=true" >> $GITHUB_ENV - run: npm install --ignore-scripts - run: npm run test + - run: npm run test-types-nodenext - uses: coverallsapp/github-action@v1.1.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index 23c4d1e5..7b2bf660 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "scripts": { "test": "c8 --reporter=lcov --reporter=text jasmine spec/*spec.js", "test-types": "tsc --noEmit spec/typings/typings-test.ts", + "test-types-nodenext": "tsc --noEmit -p spec/typings/tsconfig.nodenext.json", "unit": "jasmine", "coverage": "nyc report --reporter html --reporter text -t .nyc_output --report-dir .nyc_output/summary", "perf": "node ./benchmark/perfTest3.js", diff --git a/spec/typings/nodenext-import-test.ts b/spec/typings/nodenext-import-test.ts new file mode 100644 index 00000000..264bf762 --- /dev/null +++ b/spec/typings/nodenext-import-test.ts @@ -0,0 +1,10 @@ +/** + * Regression for GH-808: ESM declaration must use NodeNext-valid relative specifiers + * (e.g. `./pem.js` → resolves to `pem.d.ts`) so consumers with `moduleResolution: "NodeNext"` + * and `skipLibCheck: false` do not hit TS2834. + * + * Resolves the same entry as the package `import` types (`./src/fxp.d.ts`). + */ +import type { XMLParser } from "../../src/fxp.js"; + +type _Smoke = XMLParser; diff --git a/spec/typings/tsconfig.nodenext.json b/spec/typings/tsconfig.nodenext.json new file mode 100644 index 00000000..d607e547 --- /dev/null +++ b/spec/typings/tsconfig.nodenext.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true, + "skipLibCheck": false, + "noEmit": true, + "types": [] + }, + "include": ["nodenext-import-test.ts"] +} From 5a10d72fa6bca7eb65742ef2920d03355843ea98 Mon Sep 17 00:00:00 2001 From: Tom Quist Date: Mon, 23 Mar 2026 13:32:09 +0100 Subject: [PATCH 3/4] chore(types): share spec/typings tsconfig via tsconfig.base.json --- spec/typings/tsconfig.base.json | 8 ++++++++ spec/typings/tsconfig.nodenext.json | 7 ++----- 2 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 spec/typings/tsconfig.base.json diff --git a/spec/typings/tsconfig.base.json b/spec/typings/tsconfig.base.json new file mode 100644 index 00000000..5eb990a3 --- /dev/null +++ b/spec/typings/tsconfig.base.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "strict": true, + "noEmit": true, + "skipLibCheck": false, + "types": [] + } +} diff --git a/spec/typings/tsconfig.nodenext.json b/spec/typings/tsconfig.nodenext.json index d607e547..50377391 100644 --- a/spec/typings/tsconfig.nodenext.json +++ b/spec/typings/tsconfig.nodenext.json @@ -1,11 +1,8 @@ { + "extends": "./tsconfig.base.json", "compilerOptions": { "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true, - "skipLibCheck": false, - "noEmit": true, - "types": [] + "moduleResolution": "NodeNext" }, "include": ["nodenext-import-test.ts"] } From 099650774105e22eb80faa728da5813ad7db4af1 Mon Sep 17 00:00:00 2001 From: Tom Quist Date: Mon, 23 Mar 2026 13:32:50 +0100 Subject: [PATCH 4/4] chore(types): drop tsconfig.base.json; inline nodenext options --- spec/typings/tsconfig.base.json | 8 -------- spec/typings/tsconfig.nodenext.json | 7 +++++-- 2 files changed, 5 insertions(+), 10 deletions(-) delete mode 100644 spec/typings/tsconfig.base.json diff --git a/spec/typings/tsconfig.base.json b/spec/typings/tsconfig.base.json deleted file mode 100644 index 5eb990a3..00000000 --- a/spec/typings/tsconfig.base.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "strict": true, - "noEmit": true, - "skipLibCheck": false, - "types": [] - } -} diff --git a/spec/typings/tsconfig.nodenext.json b/spec/typings/tsconfig.nodenext.json index 50377391..d607e547 100644 --- a/spec/typings/tsconfig.nodenext.json +++ b/spec/typings/tsconfig.nodenext.json @@ -1,8 +1,11 @@ { - "extends": "./tsconfig.base.json", "compilerOptions": { "module": "NodeNext", - "moduleResolution": "NodeNext" + "moduleResolution": "NodeNext", + "strict": true, + "skipLibCheck": false, + "noEmit": true, + "types": [] }, "include": ["nodenext-import-test.ts"] }