Skip to content

Commit

Permalink
Add types for FunctionComponent w/o used props
Browse files Browse the repository at this point in the history
Closes GH-26.

Reviewed-by: Titus Wormer <[email protected]>
Reviewed-by: Christian Murphy <[email protected]>
Reviewed-by: Remco Haszing <[email protected]>

Co-authored-by: Christian Murphy <[email protected]>
  • Loading branch information
ignatiusreza and ChristianMurphy authored Jan 19, 2021
1 parent 39d5178 commit d5bb6b2
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 19 deletions.
54 changes: 36 additions & 18 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Minimum TypeScript Version: 3.4
// Minimum TypeScript Version: 3.8

import {Transformer} from 'unified'
import {Prefix, CreateElementLike} from 'hast-to-hyperscript'
Expand All @@ -7,14 +7,20 @@ import {Node} from 'unist'
declare namespace rehypeReact {
type FragmentLike<T> = (props: any) => T | null

interface ComponentProps {
[prop: string]: unknown
node?: Node
type ComponentPropsWithoutNode = Record<string, unknown>

interface ComponentPropsWithNode extends ComponentPropsWithoutNode {
node: Node
}

type ComponentLike<T> = (props: ComponentProps) => T | null
type ComponentProps = ComponentPropsWithoutNode | ComponentPropsWithNode

type ComponentLike<
T,
P extends ComponentPropsWithoutNode = ComponentPropsWithoutNode
> = (props: P) => T | null

interface Options<H extends CreateElementLike> {
interface SharedOptions<H extends CreateElementLike> {
/**
* How to create elements or components.
* You should typically pass `React.createElement`
Expand All @@ -27,25 +33,37 @@ declare namespace rehypeReact {
*/
Fragment?: FragmentLike<ReturnType<H>>

/**
* Override default elements (such as `<a>`, `<p>`, etcetera) by passing an object mapping tag names to components
*/
components?: Record<string, ComponentLike<ReturnType<H>>>

/**
* React key prefix
*
* @defaultValue 'h-'
*/
prefix?: Prefix

/**
* Expose HAST Node objects to `node` prop of react components
*
* @defaultValue false
*/
passNode?: boolean
}

type ComponentOptions<H extends CreateElementLike> =
| {
/**
* Override default elements (such as `<a>`, `<p>`, etcetera) by passing an object mapping tag names to components
*/
components?: Record<
string,
ComponentLike<ReturnType<H>, ComponentPropsWithNode>
>
/**
* Expose HAST Node objects to `node` prop of react components
*
* @defaultValue false
*/
passNode: true
}
| {
components?: Record<string, ComponentLike<ReturnType<H>>>
passNode?: false
}

type Options<H extends CreateElementLike> = SharedOptions<H> &
ComponentOptions<H>
}

/**
Expand Down
30 changes: 29 additions & 1 deletion types/rehype-react-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import {h as virtualDomCreateElement} from 'virtual-dom'
import * as hyperscriptCreateElement from 'hyperscript'
import Vue from 'vue'

const TypedFunctionalComponent: React.FunctionComponent = () => <>example</>
const ConflictingTypedFunctionalComponent: React.FunctionComponent<{
notARealProp: string
}> = () => null

// Create element must be provided
unified().use(rehypeToReact) // $ExpectError
unified().use(rehypeToReact, {}) // $ExpectError
Expand Down Expand Up @@ -43,6 +48,20 @@ unified().use(rehypeToReact, {
}
})

unified().use(rehypeToReact, {
createElement: React.createElement,
components: {
div: TypedFunctionalComponent
}
})

unified().use(rehypeToReact, {
createElement: React.createElement,
components: {
div: ConflictingTypedFunctionalComponent // $ExpectError
}
})

unified().use(rehypeToReact, {
createElement: React.createElement,
passNode: true
Expand All @@ -52,7 +71,16 @@ unified().use(rehypeToReact, {
createElement: React.createElement,
passNode: true,
components: {
a: (props: rehypeToReact.ComponentProps) => <a>{props.node}</a>
a: (props: rehypeToReact.ComponentPropsWithNode) => <a>{props.node}</a>
}
})

// $ExpectError
unified().use(rehypeToReact, {
createElement: React.createElement,
passNode: false,
components: {
a: (props: rehypeToReact.ComponentPropsWithNode) => <a>{props.node}</a>
}
})

Expand Down

0 comments on commit d5bb6b2

Please sign in to comment.