Skip to content

types: emitted .d.ts use extensionless relative imports, which node16 resolution rejects #769

Description

@tyler-reitz

Problem

The emitted .d.ts files use extensionless relative specifiers (from './useObservable'), which node16/nodenext module resolution rejects. TypeScript consumers on those settings get resolution errors reading our declarations.

Measured against the current build (npx tsc && npx vite build):

  • 16 extensionless relative imports across 10 emitted .d.ts files, plus 6 bare directory specifiers (from './'), which node16 also rejects.
  • The most repeated one is from './useObservable' (5 occurrences); every submodule entry (./auth, ./database, ./firestore, ./functions, ./performance, ./remote-config, ./sdk, ./storage) contributes one from src/index.ts.

The cause is in source, not in the build: src/index.ts re-exports with export * from './auth' and friends, and tsc emits specifiers unchanged. So the fix belongs in src, which is why it was kept out of #766.

Why this is filed now

#766 adds @arethetypeswrong/cli to CI. Without a suppression it fails on this, so the PR ships:

// .attw.json
{ "ignoreRules": ["internal-resolution-error"] }

attw offers nothing narrower than a rule-global ignore, so that entry also hides any future error of the same class, not just this one. The suppression is only defensible while it is temporary, and right now nothing tracks that.

Acceptance test

Delete the ignoreRules entry from .attw.json and have the Verify package job stay green. That is the whole test. If the ignore cannot be removed, the fix is incomplete.

Notes

  • Fixing this means adding explicit extensions to relative specifiers in src (./useObservable.js style, which is what node16 wants even from .ts sources), and giving ./ re-exports a concrete file.
  • Worth checking whether moduleResolution in tsconfig.json should move in the same change, so the compiler enforces this rather than leaving it to attw in CI.
  • Scope is declarations only. The runtime bundles resolve fine today, so this is not a user-visible runtime break, only a types-resolution one.

Evidence for the attw behavior (that the rule fires on exactly this class, and that suppressing it hides nothing else) was recorded when #766 was built; the counts above are from a fresh build today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions