Skip to content

feat: convert the package into TypeScript#509

Open
wandri wants to merge 9 commits intodagrejs:masterfrom
wandri:feat-convert-the-package-into-TypeScript
Open

feat: convert the package into TypeScript#509
wandri wants to merge 9 commits intodagrejs:masterfrom
wandri:feat-convert-the-package-into-TypeScript

Conversation

@wandri
Copy link

@wandri wandri commented Feb 23, 2026

Overview

This PR migrates the entire @dagrejs/dagre codebase from JavaScript to TypeScript (native source, not just type declarations). All source files, tests, and tooling scripts have been converted, and the build pipeline has been updated accordingly.

It's linked to dagrejs/graphlib#223.

Why

@dagrejs/dagre has been shipping a hand-written index.d.ts alongside its JavaScript source for a while. This approach is inherently fragile, the type declarations and the actual implementation are two separate things that have to be kept in sync manually. I ran into type drift issues and decided the cleanest fix was to rewrite the source in TypeScript directly, so types and implementation can never diverge again.

What changed

Source & Tests

  • Converted all lib/**/*.js.ts (layout engine, ordering, ranking, positioning, utilities)
  • Converted all test/**/*.js.ts
  • Converted tooling scripts (build.js, src/**/*.js) → .ts
  • Added lib/types.ts with shared interfaces and type aliases used across the codebase
  • Removed the hand-written index.d.ts — types are now generated directly from the source

Tooling

  • Replaced build.js with build.ts (run via tsx)
  • Added tsconfig.json (strict mode) and tsconfig.build.json for declaration emit
  • Added tsconfig.test.json for Jest/ts-jest configuration
  • Replaced jest.config.js with jest.config.ts using ts-jest
  • Updated .eslintrc.json to use @typescript-eslint parser and plugin
  • Added new npm scripts: typecheck, bench, version:check, version:bump, version:make
  • Added prepublishOnly to ensure typecheck, lint, tests, and build always pass before publishing

Types output

  • Removed the hand-written monolithic index.d.ts
  • Types are now auto-generated from source via tsc -p tsconfig.build.json into dist/types/
  • Updated exports and types fields in package.json to point to dist/types/index.d.ts

Advantages of the TypeScript version

Before (JS + manual index.d.ts) After (native TS)
Type safety Hand-maintained declarations, easy to drift Types derived directly from implementation — always in sync
IntelliSense Partial (from .d.ts stubs) Full, including function signatures and return types
Null safety Runtime surprises Strict null checks catch undefined cases at compile time
Refactoring safety Risky — renaming in source didn't update types Compiler catches all mismatches instantly
Maintainability Two things to keep in sync (source + .d.ts) Single source of truth
Test coverage JS tests TS tests — type errors in tests are caught before running
Tooling ESLint (JS-only config), manual build script ESLint + @typescript-eslint, tsx, ts-jest

Breaking changes

  • Version bumped to 3.0.0-pre — this is a major version given the nature of the migration and the removal of the old hand-written declaration file.
  • The types entry point has moved from dist/dagre.d.ts to dist/types/index.d.ts. If you reference the type path directly (e.g. in paths in tsconfig.json), update accordingly. The exports field handles this automatically for modern toolchains.

@celluj34
Copy link

FWIW when I import this like "@dagrejs/dagre": "https://github.com/wandri/dagre-ts/tree/feat-convert-the-package-into-TypeScript/lib" I'm getting an error:

Could not find a declaration file for module '@dagrejs/dagre'. 'c:/Users/jgc/source/repos/gms-api/ui/node_modules/@dagrejs/dagre/dist/dagre.esm.js' implicitly has an 'any' type.
Try npm i --save-dev @types/dagrejs__dagre if it exists or add a new declaration (.d.ts) file containing declare module '@dagrejs/dagre';ts(7016)

@wandri wandri force-pushed the feat-convert-the-package-into-TypeScript branch from 1ca7425 to 5a15c8d Compare February 24, 2026 17:17
@wandri
Copy link
Author

wandri commented Feb 24, 2026

Thanks @celluj34 for reporting the error. I forgot to add the dist folder in my package. It is fixed now.

@wandri
Copy link
Author

wandri commented Feb 25, 2026

The Typescript Graphlib package from dagrejs/graphlib#224 works perfectly with this version since there are no breaking changes.

@wandri
Copy link
Author

wandri commented Feb 27, 2026

I have added demo.html to test that the dist package works as expected.

image

@wandri wandri force-pushed the feat-convert-the-package-into-TypeScript branch from c509f33 to 67e7190 Compare February 28, 2026 12:15
@wandri
Copy link
Author

wandri commented Feb 28, 2026

The tests in the github workflow are finally working as expected @rustedgrail

image .

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