From d8dcf5a9277a36d85b683abff41d3487f206eb9c Mon Sep 17 00:00:00 2001 From: Christian Murphy Date: Wed, 25 Aug 2021 11:44:10 -0700 Subject: [PATCH 1/4] types: update to match new hast types, correctly compile intrinsics --- lib/ast-to-react.js | 24 +++++++----------------- lib/custom-types.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 lib/custom-types.ts diff --git a/lib/ast-to-react.js b/lib/ast-to-react.js index 8b8bd308..1357096a 100644 --- a/lib/ast-to-react.js +++ b/lib/ast-to-react.js @@ -1,14 +1,15 @@ /** - * @typedef {JSX.IntrinsicElements} IntrinsicElements * @typedef {import('react').ReactNode} ReactNode * @typedef {import('unist').Position} Position * @typedef {import('hast').Element} Element + * @typedef {import('hast').ElementContent} ElementContent * @typedef {import('hast').Root} Root * @typedef {import('hast').Text} Text * @typedef {import('hast').Comment} Comment * @typedef {import('hast').DocType} Doctype * @typedef {import('property-information').Info} Info * @typedef {import('property-information').Schema} Schema + * @typedef {import('./custom-types').ReactMarkdownProps} ReactMarkdownProps * * @typedef Raw * @property {'raw'} type @@ -21,7 +22,7 @@ * * @callback TransformLink * @param {string} href - * @param {Array.} children + * @param {Array.} children * @param {string?} title * @returns {string} * @@ -33,22 +34,14 @@ * * @callback TransformLinkTarget * @param {string} href - * @param {Array.} children + * @param {Array.} children * @param {string?} title * @returns {string|undefined} * - * @typedef {keyof IntrinsicElements} ReactMarkdownNames + * @typedef {keyof JSX.IntrinsicElements} ReactMarkdownNames * * To do: is `data-sourcepos` typeable? * - * @typedef ReactMarkdownProps - * @property {Element} node - * @property {string} key - * @property {ReactNode[]} children - * @property {Position?} [sourcePosition] Passed when `options.rawSourcePos` is given - * @property {number} [index] Passed when `options.includeElementIndex` is given - * @property {number} [siblingCount] Passed when `options.includeElementIndex` is given - * * @callback CodeComponent * @param {JSX.IntrinsicElements['code'] & ReactMarkdownProps & {inline?: boolean}} props * @returns {ReactNode} @@ -92,8 +85,7 @@ * @property {TableRowComponent|ReactMarkdownNames} tr * @property {UnorderedListComponent|ReactMarkdownNames} ul * - * @typedef {{[TagName in keyof IntrinsicElements]: TagName | ((props: IntrinsicElements[TagName] & ReactMarkdownProps) => ReactNode)}} NormalComponents - * @typedef {Partial & SpecialComponents>} Components + * @typedef {Partial & SpecialComponents>} Components * * @typedef Options * @property {boolean} [sourcePos=false] @@ -145,10 +137,8 @@ export function childrenToReact(context, node) { ) { children.push(child.value) } - // @ts-expect-error `raw` nodes are non-standard } else if (child.type === 'raw' && !context.options.skipHtml) { // Default behavior is to show (encoded) HTML. - // @ts-expect-error `raw` nodes are non-standard children.push(child.value) } } @@ -201,7 +191,7 @@ function toReact(context, node, index, parent) { context.schema = parentSchema // Nodes created by plugins do not have positional info, in which case we use - // an object that matches the positon interface. + // an object that matches the position interface. const position = node.position || { start: {line: null, column: null, offset: null}, end: {line: null, column: null, offset: null} diff --git a/lib/custom-types.ts b/lib/custom-types.ts new file mode 100644 index 00000000..32643411 --- /dev/null +++ b/lib/custom-types.ts @@ -0,0 +1,31 @@ +import {ReactNode} from 'react' +import {Position} from 'unist' +import {Element} from 'hast' + +/* File for types which are not handled correctly in JSDoc mode */ + +export interface ReactMarkdownProps { + node: Element + key: string + children: ReactNode[] + /** + * Passed when `options.rawSourcePos` is given + */ + sourcePosition?: Position + /** + * Passed when `options.includeElementIndex` is given + */ + index?: number + /** + * Passed when `options.includeElementIndex` is given + */ + siblingCount?: number +} + +export type NormalComponents = { + [TagName in keyof JSX.IntrinsicElements]: + | TagName + | (( + props: JSX.IntrinsicElements[TagName] & ReactMarkdownProps + ) => ReactNode) +} From f824c9cb0b04ed17e61e39ebdf4d1a6a9acfba76 Mon Sep 17 00:00:00 2001 From: Christian Murphy Date: Wed, 25 Aug 2021 14:10:33 -0700 Subject: [PATCH 2/4] types: refactor to use component type and remove key Co-authored-by: Remco Haszing --- lib/custom-types.ts | 7 ++----- test/test.jsx | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/custom-types.ts b/lib/custom-types.ts index 32643411..f192306e 100644 --- a/lib/custom-types.ts +++ b/lib/custom-types.ts @@ -1,4 +1,4 @@ -import {ReactNode} from 'react' +import {ReactNode, ComponentType} from 'react' import {Position} from 'unist' import {Element} from 'hast' @@ -6,7 +6,6 @@ import {Element} from 'hast' export interface ReactMarkdownProps { node: Element - key: string children: ReactNode[] /** * Passed when `options.rawSourcePos` is given @@ -25,7 +24,5 @@ export interface ReactMarkdownProps { export type NormalComponents = { [TagName in keyof JSX.IntrinsicElements]: | TagName - | (( - props: JSX.IntrinsicElements[TagName] & ReactMarkdownProps - ) => ReactNode) + | ComponentType } diff --git a/test/test.jsx b/test/test.jsx index 4a3cc0ba..6910b975 100644 --- a/test/test.jsx +++ b/test/test.jsx @@ -757,6 +757,7 @@ test('should pass on raw source position to non-tag components if rawSourcePos o rawSourcePos rehypePlugins={[raw]} components={{ + // @ts-expect-error JSX types currently only handle element returns not string returns em({sourcePosition}) { assert.equal(sourcePosition, { start: {line: 1, column: 1, offset: 0}, From 6b9f2d750e2da91ac52f65411dd1d65f1ab86864 Mon Sep 17 00:00:00 2001 From: Christian Murphy Date: Wed, 25 Aug 2021 17:17:02 -0700 Subject: [PATCH 3/4] types: ensure no JS code leaks into types file by using `import type` --- lib/custom-types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/custom-types.ts b/lib/custom-types.ts index f192306e..a46474c2 100644 --- a/lib/custom-types.ts +++ b/lib/custom-types.ts @@ -1,6 +1,6 @@ -import {ReactNode, ComponentType} from 'react' -import {Position} from 'unist' -import {Element} from 'hast' +import type {ReactNode, ComponentType} from 'react' +import type {Position} from 'unist' +import type {Element} from 'hast' /* File for types which are not handled correctly in JSDoc mode */ From e8f338a59b1329d642b21544f356f5ca0d2ff53d Mon Sep 17 00:00:00 2001 From: Christian Murphy Date: Thu, 26 Aug 2021 06:23:13 -0700 Subject: [PATCH 4/4] types: rename complex typing file, support any intrinsic element name --- lib/ast-to-react.js | 4 ++-- lib/{custom-types.ts => complex-types.ts} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename lib/{custom-types.ts => complex-types.ts} (95%) diff --git a/lib/ast-to-react.js b/lib/ast-to-react.js index 1357096a..0377a22a 100644 --- a/lib/ast-to-react.js +++ b/lib/ast-to-react.js @@ -9,7 +9,7 @@ * @typedef {import('hast').DocType} Doctype * @typedef {import('property-information').Info} Info * @typedef {import('property-information').Schema} Schema - * @typedef {import('./custom-types').ReactMarkdownProps} ReactMarkdownProps + * @typedef {import('./complex-types').ReactMarkdownProps} ReactMarkdownProps * * @typedef Raw * @property {'raw'} type @@ -85,7 +85,7 @@ * @property {TableRowComponent|ReactMarkdownNames} tr * @property {UnorderedListComponent|ReactMarkdownNames} ul * - * @typedef {Partial & SpecialComponents>} Components + * @typedef {Partial & SpecialComponents>} Components * * @typedef Options * @property {boolean} [sourcePos=false] diff --git a/lib/custom-types.ts b/lib/complex-types.ts similarity index 95% rename from lib/custom-types.ts rename to lib/complex-types.ts index a46474c2..c4df54a5 100644 --- a/lib/custom-types.ts +++ b/lib/complex-types.ts @@ -23,6 +23,6 @@ export interface ReactMarkdownProps { export type NormalComponents = { [TagName in keyof JSX.IntrinsicElements]: - | TagName + | keyof JSX.IntrinsicElements | ComponentType }