Allow adding explicitly typed nodes/edges (#80)

Summary:
Flow doesn’t allow us to specify variance annotations in generic
function parameters, and doesn’t allow coercing `Node<T>` to
`Node<mixed>`. This forces us to put `any`s in our code, which…works.

Paired with @dandelionmane.

Test Plan:
New unit tests trivially pass dynamically, and now pass statically
(failing before the changes to `graph.js`).

wchargin-branch: explicitly-typed-nodes-edges
This commit is contained in:
Dandelion Mané 2018-03-17 00:28:33 -07:00 committed by GitHub
parent 1e791782d5
commit 894d6a2291
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 6 deletions

View File

@ -17,13 +17,13 @@ export type Edge<T> = {|
|};
export type GraphJSON = {|
+nodes: AddressMapJSON<Node<mixed>>,
+edges: AddressMapJSON<Edge<mixed>>,
+nodes: AddressMapJSON<Node<any>>,
+edges: AddressMapJSON<Edge<any>>,
|};
export class Graph {
_nodes: AddressMap<Node<mixed>>;
_edges: AddressMap<Edge<mixed>>;
_nodes: AddressMap<Node<any>>;
_edges: AddressMap<Edge<any>>;
// The keyset of each of the following fields should equal the keyset
// of `_nodes`. If `e` is an edge from `u` to `v`, then `e.address`
@ -66,7 +66,7 @@ export class Graph {
return result;
}
addNode(node: Node<mixed>) {
addNode(node: Node<any>) {
if (node == null) {
throw new Error(`node is ${String(node)}`);
}
@ -88,7 +88,7 @@ export class Graph {
return this;
}
addEdge(edge: Edge<mixed>) {
addEdge(edge: Edge<any>) {
if (edge == null) {
throw new Error(`edge is ${String(edge)}`);
}

View File

@ -2,6 +2,7 @@
import type {Address, Addressable} from "./address";
import {sortedByAddress} from "./address";
import type {Node, Edge} from "./graph";
import {Graph} from "./graph";
import * as demoData from "./graphDemoData";
@ -545,5 +546,45 @@ describe("graph", () => {
expect(Graph.fromJSON(json()).toJSON()).toEqual(json());
});
});
describe("type-checking", () => {
it("allows adding explicitly typed nodes", () => {
expect(() => {
const stringNode: Node<string> = {
address: demoData.makeAddress("hello"),
payload: "hello",
};
const numberNode: Node<number> = {
address: demoData.makeAddress("hello"),
payload: 17,
};
new Graph().addNode(stringNode).addNode(numberNode);
});
});
it("allows adding explicitly typed edges", () => {
expect(() => {
const src = {address: demoData.makeAddress("src"), payload: {}};
const dst = {address: demoData.makeAddress("dst"), payload: {}};
const stringEdge: Edge<string> = {
address: demoData.makeAddress("hello"),
src: src.address,
dst: dst.address,
payload: "hello",
};
const numberEdge: Edge<number> = {
address: demoData.makeAddress("hello"),
src: src.address,
dst: dst.address,
payload: 18,
};
new Graph()
.addNode(src)
.addNode(dst)
.addEdge(stringEdge)
.addEdge(numberEdge);
});
});
});
});
});