Skip to content

feat: convert the package into TypeScript#223

Merged
rustedgrail merged 4 commits intodagrejs:masterfrom
wandri:master
Mar 8, 2026
Merged

feat: convert the package into TypeScript#223
rustedgrail merged 4 commits intodagrejs:masterfrom
wandri:master

Conversation

@wandri
Copy link
Contributor

@wandri wandri commented Feb 20, 2026

Overview

This PR migrates the entire @dagrejs/graphlib 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.

Why

I've been relying on dagrejs/dagre for a while, which depends on @dagrejs/graphlib. And I have met some typing issues in the last updates. I figured the best way to fix it properly was to rewrite the source in TypeScript — so types and implementation can never drift apart again.

NO BREAKING CHANGES

The types are isomorphic with the previous types. However, this is artificial.

WARNING 🚨

The migration has revealed real typing errors.

For example, the graph methods should have graph(): GraphLabel | undefined, node(name: string): NodeLabel | undefined, and edge(v: string | Edge, w?: string, name?: string): EdgeLabel | undefined. This could lead to errors.


What changed

Source & Tests

  • Converted all lib/**/*.js.ts (graph, algorithms, data structures)
  • Converted all test/**/*.js.ts
  • Converted build and release scripts (build.js, src/**/*.js) → .ts
  • Added a dedicated lib/types.ts file with shared interfaces (GraphOptions, Edge, Path) and type aliases (WeightFunction, EdgeFunction, NodeLabelFactory, EdgeLabelFactory)

Tooling

  • Replaced build.js with build.ts (run via tsx)
  • Added tsconfig.json (strict mode) and tsconfig.build.json for declaration emit
  • Replaced jest.config.js with jest.config.ts using ts-jest
  • Replaced .jshintrc linting with @typescript-eslint
  • Added new npm scripts: typecheck, bench, version:check, version:bump, version:make
  • Added prepublishOnly to ensure the build and tests always pass before publishing

Types output

  • Removed the hand-written monolithic dist/graphlib.d.ts / index.d.ts
  • Types are now auto-generated from the 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 .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 generics on node/edge labels
Generics Not available Graph<NodeLabel, EdgeLabel>, NodeLabelFactory<T>, EdgeLabelFactory<T>
Algorithms API Untyped inputs/outputs Strongly typed WeightFunction, EdgeFunction, Path
Refactoring safety Risky — rename in source didn't update types Compiler catches all mismatches instantly
Null safety Runtime surprises Strict null checks catch undefined edge cases at compile time
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 JSHint, manual build script ESLint + @typescript-eslint, tsx, ts-jest

Breaking changes

  • Version bumped to 4.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/graphlib.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.

@wandri
Copy link
Contributor Author

wandri commented Feb 25, 2026

I have update the PR to have ISO types. and I have added this part to the description

NO BREAKING CHANGES

The types are isomorphic with the previous types. However, this is artificial.

WARNING 🚨

The migration has revealed real typing errors.

For example, the graph methods should have graph(): GraphLabel | undefined, node(name: string): NodeLabel | undefined, and edge(v: string | Edge, w?: string, name?: string): EdgeLabel | undefined. This could lead to errors.

@rustedgrail
Copy link
Collaborator

Thanks for doing this!

Looks like there is a missing library

https://github.com/dagrejs/graphlib/actions/runs/22388294481/job/65239806208?pr=223

@wandri
Copy link
Contributor Author

wandri commented Feb 28, 2026

Thanks @rustedgrail , I have fixed the github workflow

image

@rustedgrail rustedgrail merged commit 4917fdb into dagrejs:master Mar 8, 2026
1 check passed
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