dagrejs/dagre

How to make use of `Graph<T>` / `Node<T>` types?

voxpelli opened this issue · 7 comments

@dagrejs/dagre exposes eg. Graph<T>, Node<T> types while @dagrejs/graphlib doesn't, but it's not clear how to use these to provide extended values on a node in the graph.

The node is returned using the extended Node<T>:

node(id: string | Label): Node<T>;

But there is no way of assigning any T data to it in the first place?

setNode(name: string, label: string | Label): Graph<T>;

How are these meant to be used? Considering that the plain types from @dagrejs/graphlib are not used there is a use case I assume?

Same question here.

import { dagre } from 'dagre-d3';
const g = dagre.graphlib.Graph<Your type here>(opt)

@voxpelli

import { dagre } from 'dagre-d3';
const g = dagre.graphlib.Graph<Your type here>(opt)

@voxpelli

This is not answering the question at all.

Looking at the type definitions again, the answer is this:

export type Node<T = {}> = T & {

Which means that we can do things like:

type A = {foo: string};
const g: Graph<T> = ...
const n: Node<T> = g.node("node-id");
n.foo = "bar"; // type-safe, known to be a string attribute

To be fair, this is only type-safe if T has only optional attributes, because:

type A = {foo: string};
const g: Graph<T> = ...
const n: Node<T> = g.node("node-id");
console.log(n.foo); // undefined, but should be string

This generic type T in these lines:

node(id: string | Label): Node<T>;

and
setNode(name: string, label: string | Label): Graph<T>;

come from the class definition:
class Graph<T = {}> {

So you need to provide the type when initializing new graph:

import { dagre } from 'dagre-d3';
const g = dagre.graphlib.Graph<Your type here>(opt)

We can then infer the type from those function. Note that we don't need to declare the type for n

type A = {foo: string};
const g = dagre.graphlib.Graph<A>(opt)
const n = g.node("node-id");
console.log(n.foo); // type of n.foo is string

You also can provide the type for Node<T> if you don't want to infer the type:

const n: Node<A> = {...}

This is a very basic typescript syntax, not related to dagrejs at all.
IMO I think we should close this issue

Once again you fail to understand the question. We are not asking about the syntax of the generic parameter but about how to make use of it in this context, since it does not appear in any method signature. See my comment above which answers the question for me and hopefully also for @voxpelli.
Unrelatedly, note that in your code above n.foo is undefined but supposed to be of type string.