The generated declarations do not resolve under Node's module resolution - #47
leandromatos wants to merge 1 commit into
Conversation
|
I was able to recreate the module resolution errors you described. Thank you for brining this to our attention. We will release a fix for this in the next public release sometime next week. As you mentioned, the SDK source code is generated from internal Garmin repositories, so changing code via a PR would eventually be overwritten. I'll reach out on this PR and close it once the new version of the SDK is published. |
|
This has been completed as of the 21.217 release. Let us know if this works for you. In testing, we found module resolution to be successful. |
|
Thank you for getting this into the generator. I went to upgrade and 21.217 does not appear to be published yet. Happy to confirm the resolution as soon as it lands — the reproduction from this PR is ready to run |
|
I see it published here https://www.npmjs.com/package/@garmin/fitsdk/v/21.217.0 It is still pretty fresh, so the package may not have propagated yet. |
|
Confirmed on 21.217.0! Thank you.
|
Thank you for publishing the SDK with its TypeScript declarations. Having the types ship with the
package is what makes it pleasant to work with, and this report is about one thing keeping them
from reaching part of the audience.
I read the earlier pull requests here and understand this repository publishes the SDK rather than
developing it, so the diff attached is a demonstration of the expected output and not a change to
merge. What follows is the reproduction and the cause, and the fix belongs wherever these files are
generated.
What happens
The package's public symbols do not reach a TypeScript project that resolves modules the way Node
does:
The symbols are there at runtime. Only the types are lost, so the workaround is a hand-written
declare module '@garmin/fitsdk'in the consuming project, which is the situation shippeddeclarations exist to remove.
Who it affects
Consumers compiling with
"moduleResolution": "node16"or"nodenext", the settings that matchNode's own ESM resolution. Consumers on
"moduleResolution": "bundler"are unaffected, which isprobably why this has not surfaced: this repository's
tsconfig.jsonusesbundler, so thedeclarations type-check here exactly as they do not for a consumer on Node resolution.
Reproduction
Verified against
@garmin/fitsdk@21.214.0with TypeScript 6.0.3 on Node 24.tsconfig.json:{ "compilerOptions": { "module": "nodenext", "moduleResolution": "nodenext", "strict": true, "noEmit": true } }index.ts:Compiling reports 12 errors: two
TS2305inindex.ts, one per imported symbol, and tenTS2834in
src/index.d.ts, one per re-export.Adding
"skipLibCheck": truebrings it down to 2. TheTS2834disappear and the twoTS2305atthe import site remain, now with nothing left to explain them, which is the state most consumers
land in.
Cause
src/index.d.tsre-exports the generated declarations with extensionless relative specifiers:package.jsonsets"type": "module"and declares noexportsfield, so those declarations areESM. Under Node's ESM resolution a relative specifier carries its extension, so
'./types/decoder'does not resolve. TypeScript reports that inside the declaration file,
skipLibCheckhides thereport, and the consumer is left with an entry point that exports nothing.
The declarations under
src/typeshave the same shape, so nested types degrade even when aconsumer reaches a declaration file through a deep path.
decoder.d.tsimports"./stream","./mesg"and"./mesgs", for example.What would fix it
Emitting
.json every relative specifier in the generated.d.tsfiles, matching whatsrc/index.jsalready does for the runtime modules:The attached diff does exactly that. It touches 20 specifiers across six files,
src/index.d.tsand the five under
src/typesthat carry relative imports, and takes the reproduction from 12errors to 0.
pnpm testin this repository still reports 616 passing tests and no type errors.One detail worth flagging for whoever changes the generator: the specifiers appear in two forms.
src/index.d.tsuses single quotes andexport * from, while the files undersrc/typesusedouble quotes and
import { X } from. Handling only the first form leaves 10 of the 12 errors inplace, which reads like the fix did not work.
The same project on
"moduleResolution": "bundler"reports 0 both before and after, so theextension costs current consumers nothing.
These files carry a "Do NOT edit this file" banner, so this belongs in the generator rather than in
the checked-in output. Happy to test a pre-release if that is useful.