Skip to content

Conversation

@scottlovegrove
Copy link
Collaborator

Summary

Fixes #X - Resolves the type re-export issue introduced when package.json has "type": "module" where types exported from this package could not be re-exported by consuming packages.

Root Cause

When package.json has "type": "module", TypeScript treats .d.ts files as ESM modules, which require explicit file extensions (.js) for relative imports. The generated declaration files had imports like from './twist-api' instead of from './twist-api.js', causing module resolution to fail when other packages tried to re-export types.

This is the same issue that was fixed in todoist-api-typescript PR #410.

Changes

  • Added scripts/fix-dts-imports.cjs: Post-build script that adds .js extensions to all relative imports in generated .d.ts files
    • Handles import statements
    • Handles export statements
    • Handles dynamic import() type expressions
  • Updated package.json:
    • Added build:fix-dts script to run the DTS fixer
    • Updated build script to include the fix-dts step
    • Added attw script for type validation using @arethetypeswrong/cli
      • Ignores fallback-condition and false-esm rules (known limitations of dual-module packages that don't affect functionality)
    • Updated integrity-checks to include attw validation

Before vs After

Before Fix

// dist/types/index.d.ts
export * from './authentication';
export { TwistApi } from './twist-api';
export * from './types/index';

// dist/types/twist-api.d.ts  
import { ChannelsClient } from './clients/channels-client';
import type { BatchRequestDescriptor } from './types/batch';

After Fix

// dist/types/index.d.ts
export * from './authentication.js';
export { TwistApi } from './twist-api.js';
export * from './types/index.js';

// dist/types/twist-api.d.ts
import { ChannelsClient } from './clients/channels-client.js';
import type { BatchRequestDescriptor } from './types/batch.js';

Verification

Type Validation Results

Before fix (using @arethetypeswrong/cli --pack):

After fix:

  • No problems found
  • The critical InternalResolutionError that prevented type re-exports is now resolved

Testing

You can verify this fix works by running:

npm install && npm run build
npm run attw

Expected output:

@doist/twist-sdk v1.0.1
 No problems found 🌟

Test Plan

  • Build succeeds with new fix-dts step
  • Declaration files fixed - All relative imports now have .js extensions
  • Type validation passes - @arethetypeswrong/cli reports no problems
  • All tests pass - 166/166 tests passing without modification
  • TypeScript compiles - No compilation errors
  • CI integration - Type validation included in integrity checks

Compatibility

  • Zero Breaking Changes: All existing APIs work exactly as before
  • Build Process: Seamlessly integrates into existing build pipeline
  • Type Safety: Maintains full type safety while fixing module resolution
  • CI Integration: Prevents future regressions with automated type validation

Impact

  • Enables type re-exports from consuming packages
  • Prevents module resolution errors in ESM environments with dual-module packages
  • Maintains compatibility with all existing code and build processes
  • Adds regression protection via automated type validation in CI

Related Issues

This fix applies the same solution as:

The remaining warnings mentioned in the Todoist PR (FalseESM and FallbackCondition) are expected for dual-module packages and are safely ignored:

  • FalseESM: Types are marked as ESM (due to "type": "module") while CommonJS implementation has its own package.json. This is intentional for dual-module packages.
  • FallbackCondition: TypeScript's handling of the exports field has a known bug where it falls back to the types condition. This doesn't affect runtime behavior.

🤖 Generated with Claude Code

…e-export issue

Fixes type re-export issue where types exported from this package could not be
re-exported by consuming packages when package.json has "type": "module".

## Root Cause

When `package.json` has `"type": "module"`, TypeScript treats `.d.ts` files as
ESM modules, which require explicit file extensions (`.js`) for relative imports.
The generated declaration files had imports like `from './twist-api'` instead of
`from './twist-api.js'`, causing module resolution to fail when other packages
tried to re-export types.

## Changes

- **Added `scripts/fix-dts-imports.cjs`**: Post-build script that adds `.js`
  extensions to all relative imports in generated `.d.ts` files
  - Handles `import` statements
  - Handles `export` statements
  - Handles dynamic `import()` type expressions
- **Updated `package.json`**:
  - Added `build:fix-dts` script to run the DTS fixer
  - Updated `build` script to include the fix-dts step
  - Added `attw` script for type validation using `@arethetypeswrong/cli`
  - Updated `integrity-checks` to include `attw` validation

## Verification

**Before fix** (using `@arethetypeswrong/cli --pack`):
- ❌ **InternalResolutionError** - Module resolution failed (breaking bug)

**After fix**:
- ✅ **No problems found** - All module resolution working correctly ⭐
- ✅ Declaration files now have `.js` extensions on all relative imports
- ✅ Type validation passes with `@arethetypeswrong/cli`

## Test Plan

- [x] Build completes successfully with new fix-dts step
- [x] Declaration files now have `.js` extensions on all relative imports
- [x] `@arethetypeswrong/cli` validation passes (no problems found)
- [x] All 166 tests pass without modification
- [x] TypeScript compilation succeeds without errors

Applies same fix as:
- Doist/todoist-api-typescript#410

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@scottlovegrove scottlovegrove self-assigned this Nov 27, 2025
@scottlovegrove scottlovegrove merged commit 660cf10 into main Nov 27, 2025
2 of 3 checks passed
@scottlovegrove scottlovegrove deleted the scottl/fix-dts-imports branch November 27, 2025 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants