Expose `NodeTypes` from the GitHub plugin (#96)
Summary: This is useful for metaprogramming. For instance, suppose we have an object like this: ```js const stringifiers = { ISSUE: (stringifyIssue: (Node<IssueNodePayload>) => string), COMMENT: (stringifyComment: (Node<CommentPayload>) => string), ... } ``` How do we type this? We might try ```js {[type: NodeType]: (Node<NodePayload>) => string} ``` but this is not correct, because `Node<IssueNodePayload>` is a subtype of `Node<NodePayload>`, and `(_) => K` is contravariant, not covariant. (In other words, a function from `Node<IssueNodePayload>` is not as general as a function from `Node<NodePayload>`.) We need to express a dependency between the object key and the value. We instead write: ```js type TypedNodeToStringifier = <T: $Values<NodeTypes>>( T ) => (node: Node<$ElementType<T, "payload">>) => string; (stringifiers: $Exact<$ObjMap<NodeTypes, TypedNodeToStringifier>>); ``` This expresses exactly (heh) the right type. Test Plan: Note that removing any of the elements of `NodeTypes` yields a Flow error, due to the static assertion following the type definition. wchargin-branch: node-types
This commit is contained in:
parent
559ed393a9
commit
e9ca833448
|
@ -109,6 +109,61 @@ export type NodeID =
|
||||||
| AuthorNodeID;
|
| AuthorNodeID;
|
||||||
export type NodeType = $ElementType<NodeID, "type">;
|
export type NodeType = $ElementType<NodeID, "type">;
|
||||||
|
|
||||||
|
// A map from NodeType string to the corresponding ID and payload types.
|
||||||
|
// Primarily useful for adding static assertions with $ObjMap, but also
|
||||||
|
// useful at the value layer as $ElementType<NodeTypes, "ISSUE">, for
|
||||||
|
// instance.
|
||||||
|
export type NodeTypes = {|
|
||||||
|
ISSUE: {
|
||||||
|
id: IssueNodeID,
|
||||||
|
payload: IssueNodePayload,
|
||||||
|
},
|
||||||
|
PULL_REQUEST: {
|
||||||
|
id: PullRequestNodeID,
|
||||||
|
payload: PullRequestNodePayload,
|
||||||
|
},
|
||||||
|
COMMENT: {
|
||||||
|
id: CommentNodeID,
|
||||||
|
payload: CommentNodePayload,
|
||||||
|
},
|
||||||
|
PULL_REQUEST_REVIEW_COMMENT: {
|
||||||
|
id: PullRequestReviewCommentNodeID,
|
||||||
|
payload: PullRequestReviewCommentNodePayload,
|
||||||
|
},
|
||||||
|
PULL_REQUEST_REVIEW: {
|
||||||
|
id: PullRequestReviewNodeID,
|
||||||
|
payload: PullRequestReviewNodePayload,
|
||||||
|
},
|
||||||
|
USER: {
|
||||||
|
id: UserNodeID,
|
||||||
|
payload: UserNodePayload,
|
||||||
|
},
|
||||||
|
ORGANIZATION: {
|
||||||
|
id: OrganizationNodeID,
|
||||||
|
payload: OrganizationNodePayload,
|
||||||
|
},
|
||||||
|
BOT: {
|
||||||
|
id: BotNodeID,
|
||||||
|
payload: BotNodePayload,
|
||||||
|
},
|
||||||
|
|};
|
||||||
|
(function staticAssertions() {
|
||||||
|
// Check that node payload types are exhaustive.
|
||||||
|
(x: NodeType): $Keys<NodeTypes> => x;
|
||||||
|
|
||||||
|
// Check that each type is associated with the correct ID type.
|
||||||
|
// Doesn't work because of a Flow bug; should work if that bug is
|
||||||
|
// fixed: https://github.com/facebook/flow/issues/4211
|
||||||
|
// (Summary of bug: $ElementType<O, -> does not preserve unions.)
|
||||||
|
//
|
||||||
|
// <T: $Keys<NodeTypes>>(
|
||||||
|
// x: T
|
||||||
|
// ): $ElementType<
|
||||||
|
// $ElementType<$ElementType<NodeTypes, T>, "id">,
|
||||||
|
// "type"
|
||||||
|
// > => x;
|
||||||
|
});
|
||||||
|
|
||||||
export type AuthorshipEdgePayload = {};
|
export type AuthorshipEdgePayload = {};
|
||||||
export type AuthorshipEdgeID = {
|
export type AuthorshipEdgeID = {
|
||||||
+type: "AUTHORSHIP",
|
+type: "AUTHORSHIP",
|
||||||
|
|
Loading…
Reference in New Issue