The GenericNode and GenericParent types in MyST exist as an escape hatch for interacting with unified helpers like unist-util-select. However, over time they've spread throughout our codebase as types for intermediate state and function input/output types. Through using these generic types, we are not strict about whether something is "valid AST" or a superset of our AST, e.g. with user-added nodes.
I'm not 100% clear yet on what the ideal approach is. Sometimes we'll want to write generic tooling that allows user-defined node types. Other times, we are expecting a particular type.
The @types/mdast schema is closed (no support for unknown types) but it's possible to extend at compile time. Therefore, one approach is to write type signatures like
// Closed set of node
import type { Nodes } from 'myst-spec';
interface NodeLike {
type: string;
}
interface ValueLike {
type: string;
value: string;
}
interface ParentLike {
type: string;
value: string;
}
type UnknownNode = NodeLike | ValueLike | ParentLike;
function processNode(node: Nodes | UnknownNode) {
}
which then allows us to write exhaustive switches on the node type.
Definition of Done
The
GenericNodeandGenericParenttypes in MyST exist as an escape hatch for interacting withunifiedhelpers likeunist-util-select. However, over time they've spread throughout our codebase as types for intermediate state and function input/output types. Through using these generic types, we are not strict about whether something is "valid AST" or a superset of our AST, e.g. with user-added nodes.I'm not 100% clear yet on what the ideal approach is. Sometimes we'll want to write generic tooling that allows user-defined node types. Other times, we are expecting a particular type.
The
@types/mdastschema is closed (no support for unknown types) but it's possible to extend at compile time. Therefore, one approach is to write type signatures likewhich then allows us to write exhaustive switches on the node type.
Definition of Done
GenericNodetypes