mirror of
https://github.com/status-im/sourcecred.git
synced 2025-01-28 21:34:56 +00:00
Switch typed dispatch table to empty
assertion (#133)
Summary: This replaces the implementation of a static check from a somewhat complicated use of higher-order types to a more simple empty-union assertion, as suggested by jez in “Case Exhaustiveness in Flow”: https://blog.jez.io/flow-exhaustiveness/ (I know; we’re not using Reason. One step at a time. :-) ) I adapted the implementation a bit because I prefer explicitly disabling an ESLint warning over a no-op function call; it is not clear from the latter that the purpose is to suppress a lint warning. Test Plan: In `githubPlugin.js`, add `| "ANOTHER"` to the `NodeType` type, and note a compile-time Flow error on the appropriate line, with a very readable error message. Note that all unit tests pass, and running the UI on `sourcecred/sourcecred` yields correct titles for each node type present (namely, all node types except for `ORGANIZATION` and `BOT`). wchargin-branch: empty-union-assertion
This commit is contained in:
parent
1e311c59f4
commit
e0a5118f8d
@ -7,7 +7,6 @@ import type {Node} from "../../../../core/graph";
|
||||
import type {
|
||||
NodePayload,
|
||||
NodeType,
|
||||
NodeTypes,
|
||||
IssueNodePayload,
|
||||
PullRequestNodePayload,
|
||||
CommentNodePayload,
|
||||
@ -79,26 +78,27 @@ const adapter: PluginAdapter<NodePayload> = {
|
||||
function extractAuthorTitle(node: Node<AuthorNodePayload>) {
|
||||
return node.payload.login;
|
||||
}
|
||||
type TypedNodeToStringExtractor = <T: $Values<NodeTypes>>(
|
||||
T
|
||||
) => (node: Node<$ElementType<T, "payload">>) => string;
|
||||
const extractors: $Exact<$ObjMap<NodeTypes, TypedNodeToStringExtractor>> = {
|
||||
ISSUE: extractIssueOrPrTitle,
|
||||
PULL_REQUEST: extractIssueOrPrTitle,
|
||||
COMMENT: (node) => extractCommentTitle("comment", node),
|
||||
PULL_REQUEST_REVIEW_COMMENT: (node) =>
|
||||
extractCommentTitle("review comment", node),
|
||||
PULL_REQUEST_REVIEW: extractPRReviewTitle,
|
||||
USER: extractAuthorTitle,
|
||||
ORGANIZATION: extractAuthorTitle,
|
||||
BOT: extractAuthorTitle,
|
||||
};
|
||||
function fallbackAccessor(node: Node<NodePayload>) {
|
||||
throw new Error(`unknown node type: ${node.address.type}`);
|
||||
const anyNode: Node<any> = node;
|
||||
const type: NodeType = (node.address.type: any);
|
||||
switch (type) {
|
||||
case "ISSUE":
|
||||
case "PULL_REQUEST":
|
||||
return extractIssueOrPrTitle(anyNode);
|
||||
case "COMMENT":
|
||||
return extractCommentTitle("comment", anyNode);
|
||||
case "PULL_REQUEST_REVIEW_COMMENT":
|
||||
return extractCommentTitle("review comment", anyNode);
|
||||
case "PULL_REQUEST_REVIEW":
|
||||
return extractPRReviewTitle(anyNode);
|
||||
case "USER":
|
||||
case "ORGANIZATION":
|
||||
case "BOT":
|
||||
return extractAuthorTitle(anyNode);
|
||||
default:
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
(type: empty);
|
||||
throw new Error(`unknown node type: ${node.address.type}`);
|
||||
}
|
||||
return (extractors[node.address.type] || fallbackAccessor)(
|
||||
(node: Node<any>)
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user