4

I am trying to add a type definition to a .d.ts file for a React.FunctionComponent that looks like this:

Tree.propTypes = {
  root: PropTypes.object.isRequired,
  children: PropTypes.func,
  top: PropTypes.number,
  left: PropTypes.number,
  className: PropTypes.string,
  size: PropTypes.arrayOf(PropTypes.number),
  nodeSize: PropTypes.arrayOf(PropTypes.number),
  separation: PropTypes.func,
  linkComponent: PropTypes.any,
  nodeComponent: PropTypes.any
};

export default function Tree({
  top,
  left,
  className,
  root,
  size,
  nodeSize,
  separation,
  children,
  linkComponent = DefaultLink,
  nodeComponent = DefaultNode,
  ...restProps
}) {

import React from 'react'; import { TreeLayout, HierarchyPointNode, HierarchyNode } from 'd3-hierarchy';

I have come up with this approach:

export interface TreeProps<Datum, LinkComponentType = any, NodeComponentType = any> {
  root: HierarchyNode<Datum>;
  top?: number;
  left?: number;
  className?: string;
  size?: [number, number];
  linkComponent: React.ComponentType<LinkComponentType>;
  separation: (a: HierarchyPointNode<Datum>, b: HierarchyPointNode<Datum>) => number;
  nodeComponent: React.ComponentType<NodeComponentType>;
  nodeSize?: [number, number];
}


export declare function Tree<
  Datum,
  LinkComponentType = any,
  NodeComponentType = any
>(args: TreeProps<Datum, LinkComponentType, NodeComponentType>): JSX.Element;

Is this the correct way of typing this, I think it should be a React.FunctionComponent like:

export declare const Tree<Datum>

But then I would not be able to pass in the type arguments.

2
  • Why do you use the declare keyword here? Commented Jun 8, 2019 at 7:07
  • do linkComponent and nodeComponent impact the props available to the component ? It would seem like they would. Otherwise export declare function seems ok, if you want to use a const it should be export declare const Tree: < Datum, LinkComponentType = any, NodeComponentType = any >(args: TreeProps<Datum, LinkComponentType, NodeComponentType>) => JSX.Element; But I see no need to do this, they should work the same in this case Commented Jun 9, 2019 at 7:32

3 Answers 3

2
+500

You can declare a module in .d.ts:

declare module 'NAME_OF_THE_PACKAGE' {
    export interface TreeProps<Datum, LinkComponentType = any, NodeComponentType = any> {
        root: HierarchyNode<Datum>;
        top?: number;
        left?: number;
        className?: string;
        size?: [number, number];
        linkComponent: React.ComponentType<LinkComponentType>;
        separation: (a: HierarchyPointNode<Datum>, b: HierarchyPointNode<Datum>) => number;
        nodeComponent: React.ComponentType<NodeComponentType>;
        nodeSize?: [number, number];
    }

    export function Tree<Datum, LinkComponentType = any, NodeComponentType = any>(
        args: TreeProps<Datum, LinkComponentType, NodeComponentType>
    ): JSX.Element;
}

Where NAME_OF_THE_PACKAGE is exactly the name you import the package or install it via npm or yarn.

This way, you will be able to import TreeProps and Tree this way

import { TreeProps, Tree } from 'NAME_OF_THE_PACKAGE'

You can read more about modules here (check the example of how JavaScript libs are declared - "Working with Other JavaScript Libraries").

Sign up to request clarification or add additional context in comments.

Comments

0

You can declare a type like this

export type Tree<D, LC = any, NC = any> =
    React.FunctionComponent<TreeProps<D, LC, NC>> => JSX.Element

Usage

const Tree: Tree<a,b,c> = (props) => <></>

Comments

0

You can do

declare const Tree: React.FunctionComponent<TreeProps<Datum, LinkComponentType, NodeComponentType>>;

export default Tree;

Tree will be of type React.FunctionComponent<P> which is (props: PropsWithChildren<P>, context?: any): ReactElement | null; (function component).

May be you've been confused by declare keyword. The best description I found is here.

To create function of type React.FunctionComponent<P> use syntax

const Tree: React.FunctionComponent<TreeProps<Datum, LinkComponentType, NodeComponentType>> =
(props) => {
    return <div className={props.className}>
        Some div
        </div>
}

Note that here is no need for declare keyword.

4 Comments

i am creating a declaration file for a 3rd party so there is s need
Sorry, I didn't understand you comment. You mean 'so there is I need' or 'so there is no need'?
i’m writing a declaration file index.d.ts for a 3rd party library that does not have a declaration file. are you still saying i dint need declare
To declare types for third party lib you should use declare keyword. First code snippet should suit your needs. Code snippet without decalre is to difference between declaring and implementing Function component

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.