Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define defaultProps for a stateless react component in typescript?

I want to define defaultprops for my pure functional component but I get a type error:

export interface PageProps extends React.HTMLProps<HTMLDivElement> {
    toolbarItem?: JSX.Element;
    title?: string;
}

const Page = (props: PageProps) => (
    <div className="row">
        <Paper className="col-xs-12 col-sm-offset-1 col-sm-10" zDepth={1}>
            <AppBar
                title={props.title}
                zDepth={0}
                style={{ backgroundColor: "white" }}
                showMenuIconButton={false}
                iconElementRight={props.toolbarItem}
            />
            {props.children}
        </Paper>
    </div>
);

Page.defaultProps = {
    toolbarItem: null,
};

I know that I can write this:

(Page as any).defaultProps = {
    toolbarItem: null,
};

Is there a better way to add defaultProps?

like image 550
alisabzevari Avatar asked Sep 13 '16 12:09

alisabzevari


2 Answers

You can type Page like this:

const Page: StatelessComponent<PageProps> = (props) => (
    // ...
);

Then you can write Page.defaultProps without needing to cast to any (the type of defaultProps will be PageProps).

like image 84
Tom Fenech Avatar answered Nov 12 '22 01:11

Tom Fenech


This is fairly straightforward by using Javascript's own default function parameters, and with Typescript generics you will get strong correct type information both inside the component and in the outside world of component consumers.

import React, { FC } from "react";

interface MyComponentProps {
  name?: string;
}

const MyComponent: FC<MyComponentProps> = ({ name = "Someone" }) => {
  // note that Typescript knows that the property will never
  // be `undefined` inside this function
  return <div>Hello {name}</div>;
}

export default MyComponent;

And you can consume the component like so:

import React, { FC } from "react":
import MyComponent from "./MyComponent";

const ParentComponent: FC = () => {
  // Typescript knows that you name is optional
  // and will not complain if you don't provide it
  return (
    <div>
      <MyComponent />
      <MyComponent name="Jane" />
    </div>
  );
}

export default ParentComponent;
like image 23
pete otaqui Avatar answered Nov 12 '22 02:11

pete otaqui