-
Notifications
You must be signed in to change notification settings - Fork 80
fix: correct parent typing for rule visitors #571
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,35 +8,11 @@ import type { | |
| Data, | ||
| Literal, | ||
| Parent, | ||
| // Nodes | ||
| Blockquote, | ||
| Break, | ||
| Parents, | ||
| // Node unions | ||
| Nodes, | ||
| Code, | ||
| Definition, | ||
| Emphasis, | ||
| Heading, | ||
| Html, | ||
| Image, | ||
| ImageReference, | ||
| InlineCode, | ||
| Link, | ||
| LinkReference, | ||
| List, | ||
| ListItem, | ||
| Paragraph, | ||
| Root, | ||
| Strong, | ||
| Text, | ||
| ThematicBreak, | ||
| // Extensions (GFM) | ||
| Delete, | ||
| FootnoteDefinition, | ||
| FootnoteReference, | ||
| Table, | ||
| TableCell, | ||
| TableRow, | ||
| // Extensions (front matter) | ||
| Yaml, | ||
| } from "mdast"; | ||
| import type { | ||
| CustomRuleDefinitionType, | ||
|
|
@@ -58,6 +34,25 @@ type WithExit<RuleVisitorType extends RuleVisitor> = { | |
| | `${Key & string}:exit`]: RuleVisitorType[Key]; | ||
| }; | ||
|
|
||
| /** | ||
| * Compute the precise parent type for a given node `T`. | ||
| * - Root has no parent (returns `never`). | ||
| * - Custom frontmatter nodes (`toml` / `json`) only appear directly under `Root`. | ||
| * - For nodes, include every parent `P` where `T` is assignable to one of | ||
| * `P['children'][number]` (i.e. `T` can appear in `P.children`). | ||
| */ | ||
| type ParentOf<T extends MarkdownNode> = T extends Root | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be static for performance and simplicity reasons as the parent of the various markdown nodes should be easily groupable (inside paragraph (e.g.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. Also, deeply nested conditional types make the code somewhat unclear to me. |
||
| ? never | ||
| : T extends Toml | Json | ||
| ? Root | ||
| : Parents extends infer P | ||
| ? P extends Parent | ||
| ? T extends P["children"][number] | ||
| ? P | ||
| : never | ||
| : never | ||
| : never; | ||
|
|
||
| //------------------------------------------------------------------------------ | ||
| // Exports | ||
| //------------------------------------------------------------------------------ | ||
|
|
@@ -129,45 +124,19 @@ export interface MarkdownLanguageOptions extends LanguageOptions { | |
| */ | ||
| export type MarkdownLanguageContext = LanguageContext<MarkdownLanguageOptions>; | ||
|
|
||
| export type MarkdownSyntaxElement = Node; | ||
|
|
||
| type MarkdownNode = Nodes | Json | Toml; | ||
|
|
||
| type MarkdownNodeVisitor = { | ||
| [Node in MarkdownNode as Node["type"]]: Node extends Root | ||
| ? ((node: Node) => void) | undefined | ||
| : ((node: Node, parent: ParentOf<Node>) => void) | undefined; | ||
| }; | ||
|
|
||
| export interface MarkdownRuleVisitor | ||
| extends RuleVisitor, | ||
| WithExit< | ||
| { | ||
| root?(node: Root): void; | ||
| } & { | ||
| [NodeType in | ||
| | Blockquote // Nodes | ||
| | Break | ||
| | Code | ||
| | Definition | ||
| | Emphasis | ||
| | Heading | ||
| | Html | ||
| | Image | ||
| | ImageReference | ||
| | InlineCode | ||
| | Link | ||
| | LinkReference | ||
| | List | ||
| | ListItem | ||
| | Paragraph | ||
| | Strong | ||
| | Text | ||
| | ThematicBreak | ||
| | Delete // Extensions (GFM) | ||
| | FootnoteDefinition | ||
| | FootnoteReference | ||
| | Table | ||
| | TableCell | ||
| | TableRow | ||
| | Yaml // Extensions (front matter) | ||
| | Toml | ||
| | Json as NodeType["type"]]?: ( | ||
| node: NodeType, | ||
| parent?: Parent, | ||
| ) => void; | ||
| } | ||
| > {} | ||
| Partial<WithExit<MarkdownNodeVisitor>> {} | ||
|
|
||
| export type MarkdownRuleDefinitionTypeOptions = CustomRuleTypeDefinitions; | ||
|
|
||
|
|
@@ -178,7 +147,7 @@ export type MarkdownRuleDefinition< | |
| LangOptions: MarkdownLanguageOptions; | ||
| Code: MarkdownSourceCode; | ||
| Visitor: MarkdownRuleVisitor; | ||
| Node: Node; | ||
| Node: MarkdownSyntaxElement; | ||
| }, | ||
| Options | ||
| >; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally, there was consensus not to use the
RootContenttype.Currently, the
Nodestype is equivalent toRoot | RootContent, so I'm not sure that usingNodeshere is the desired approach.I personally prefer not to use the
Nodestype and to keep the original enumeration style.Ref: #334 (comment)