3

I wanted to use react stateless component in typescript with defaultProps.

I am not able to find solution how to use typings that would allow me to use defaultProps in TypeScript project without diamond syntax.

import {Link} from "react-router";

interface LinkProps {
    ...
}

const LinkPresenter = (props: LinkProps): JSX.Element =>
    <Link
        ...
    >
        ...
    </Link>;

LinkPresenter.defaultProps = { // !!! unresolved variable defaultProps
    ...
};
Marcel Mandatory
  • 1,447
  • 13
  • 25

2 Answers2

2

Type React.SFC allow to attach defaultProps to react stateless component.

Bellow you can find simplified example of React.SFC with defaultProps.

import {Link} from "react-router";

interface LinkProps {
    to?: HistoryModule.LocationDescriptorObject;
    onClick?: (event: React.FormEvent) => void;
    children?: React.ReactNode;
}

const LinkPresenter: React.SFC = (props: LinkProps): JSX.Element =>
    <Link
        className="link"
        to={props.to}
        onClick={props.onClick}
    >
        {props.children}
    </Link>;

// Alternative syntax
const LinkPresenter: React.StatelessComponent = (props: LinkProps): JSX.Element =>
...

LinkPresenter.defaultProps = { // now we can use defaultProps
    to: {
        pathname: `/homepage`,
        query: {
            default: 'someDefault'
        }
    },
    onClick: () => {},
    children: <span>Hello world</span>,
};
Marcel Mandatory
  • 1,447
  • 13
  • 25
  • 3
    but you don't need to do this with typescript, you can set the default props in the method signature i.e const LinkPresenter: React.SFC = (props: LinkProps = {to: {pathname:'',query}}): JSX.Element – Ross Scott Sep 16 '16 at 09:28
  • 1
    @RossScott that's an interesting idea, although I guess it only lets you specify the whole props object, rather than specific default properties. – Tom Fenech Sep 16 '16 at 09:37
  • @RossScott: I am new to typescript I like the syntax your suggested. – Marcel Mandatory Sep 16 '16 at 09:37
  • You can have multiple properties passed in, each with their own default value. You can also define the default value outside of the function as a variable and then assign that. – Ross Scott Sep 16 '16 at 10:41
  • this does not seem to work for me: https://stackblitz.com/edit/react-ts-ufek81 – apieceofbart Nov 03 '18 at 17:15
  • to anyone wondering this is a bug in Typescript 3.1, should be fixed when 3.2 comes out – apieceofbart Nov 04 '18 at 15:07
1

Just to expand on our conversation, here is an alternative using the TS / ES6 default property approach:

import {Link} from "react-router";

interface LinkProps {
    to?: HistoryModule.LocationDescriptorObject;
    onClick?: (event: React.FormEvent) => void;
    children?: React.ReactNode;
}

let defaultProps : LinkProps = {
  to: {
        pathname: `/homepage`,
        query: {
            default: 'someDefault'
        }
  },
  onClick: () => {},
  children: <span>Hello world</span>
}

const LinkPresenter = (props: LinkProps = defaultProps): JSX.Element =>
    <Link
        className="link"
        to={props.to}
        onClick={props.onClick}
    >
        {props.children}
    </Link>;
Ross Scott
  • 1,690
  • 9
  • 16