Repository navigation
fix(types): emit CommonJS declarations for every module - #853
Open
tyler-reitz wants to merge 4 commits into
Open
tyler-reitz wants to merge 4 commits into
tyler-reitz wants to merge 4 commits into
Conversation
The require condition's index.d.cts was a copy of index.d.ts, so its relative imports resolved to .d.ts files that TypeScript reads as ESM in this "type": "module" package. CommonJS projects using module: node16 with skipLibCheck: false got TS1479 on each one. build:types-cjs now writes a .d.cts next to every .d.ts and points relative imports at the .cjs siblings. A new Verify package step type-checks a CommonJS fixture against the packed tarball, since attw passes on the broken output. Closes FirebaseExtended#850
armando-navarro
approved these changes
Nov 12, 2026
armando-navarro
left a comment
Contributor
There was a problem hiding this comment.
Approving. The 12 TS1479 errors reproduce on main and are gone on this branch on every TypeScript version in your table, and apart from the .d.cts files and the script line in package.json, the two packed tarballs are identical.
Below are some optional considerations that don't need to hold up this PR.
1. Published 4.2.3 does not show the same errors (optional)
- The description says "This predates 4.3.0: published 4.2.3 has the same errors".
- 4.2.3 through 4.2.6 ship no
index.d.ctsand have notypesentry underrequire. - The same CommonJS project gets TS7016 on those versions: "Could not find a declaration file for module 'reactfire'".
- TS1479 first appears in published 4.3.0.
2. The pre-filled squash message describes the type-check step you removed (optional)
- This repo pre-fills the squash message from the commit messages.
- The message of
8352261says "A new Verify package step type-checks a CommonJS fixture against the packed tarball". c12ed6dremoves that step.- I'd recommend dropping that sentence when you merge.
- I could not find why the step was removed. What was the reason?
3. Two cases the script would leave unconverted (optional)
The description says a new file cannot slip through unconverted. I found two cases where a file would, with no error from the script. Neither can happen today, because src has no side-effect import and no subfolders.
- Case 1: a file in
srcgains a side-effect import, such asimport './telemetry.js'.- The script only rewrites paths that follow
fromorimport(, so this path stays.js. - On TypeScript 6.0.3 a CommonJS project then gets TS1479 again.
- On 5.9.3 that happens only with
noUncheckedSideEffectImportson. attwpasses on that package, so CI would not show it.
- The script only rewrites paths that follow
- Case 2: a declaration file ends up in a subfolder of
dist.- The script only reads the top level of
dist, so that file gets no.d.cts. - The import pointing at it is still rewritten to
.cjs. attwfails on that package, so CI does catch this one.- Passing
{ recursive: true }toreaddirSynccovers it, and the output for today'sdistis byte-identical.
- The script only reads the top level of
None of these needs another round from me.
emit-cjs-types now rewrites bare `import './x.js'` specifiers and reads dist recursively, so neither case leaves a .d.ts without its .d.cts counterpart. Output for today's dist is byte-identical.
Contributor
Author
|
Thanks Armando.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CommonJS TypeScript projects using
module: node16andskipLibCheck: falsecan importreactfirewithout TS1479.Closes #850
Cause
dist/index.d.cts(therequiretypes) was a copy ofindex.d.ts. Its relative imports resolved to.d.tsfiles, which TypeScript reads as ESM in this"type": "module"package. TS1479 first appears in 4.3.0, which addedindex.d.cts. 4.2.3 through 4.2.6 have norequiretypes, so the same projects got TS7016 there instead.Changes
build:types-cjsrunsscripts/emit-cjs-types.mjs, which writes a.d.ctsnext to everydist/*.d.tsand rewrites relative./x.jsimports to./x.cjs, so each resolves to its.d.ctssibling. It readsdistrecursively, rewritesfrom,import()and side-effect imports, and throws on a relative import without.js.No runtime change.
requiretypes without type-checking them.Testing
Fixture: CommonJS package,
module: node16,skipLibCheck: false, firebase 13.1.0, React 19.lib: esnext), CJS and ESM consumersuseUser'sstatustype is the real union, so a resolution that falls back toanyfails it (confirmed by replacing the types withany).Temporalin@firebase/firestore's own declarations. The 5.0 and 5.4 rows have more pre-existing errors; the fix removes only the TS1479s and leaves the rest unchanged.distis byte-identical before and after9aa5ad6; a testdistwith a side-effect import and a nested declaration file is fully converted by the new script and not by the old one.tsc -p tsconfig.test.jsonand oxlint are clean. Nosrcchange, so the emulator suite and docs were not re-run.