I\'m using React with TypeScript and I\'ve created stateless function. I\'ve removed useless code from the example for readability.
interface CenterBoxProps exte
Typing default props in function component with React.FC can result in false type error:
type Props = {
required: string,
} & typeof defaultProps;
const defaultProps = {
optDefault: 'optDefault'
};
const MyComponent: React.FC<Props> = (props: Props) => (
<ul>
<li>required: {props.required}</li>
<li>optDefault: {props.optDefault}</li>
</ul>
)
MyComponent.defaultProps = defaultProps;
ReactDOM.render(
<div>
<MyComponent
required='required'
optDefault='over written'
/>
<MyComponent /* type error <---- false type error */
required='required'
/>
</div>,
document.getElementById('app')
);
error:
[tsserver 2741] Property 'optDefault' is missing in type '{ required: string; }' but required in type '{ optDefault: string; }'. [E]
Another solution proposed is to use Javascript's own default function parameters:
type Props = {
required: string,
optDefault?: string
}
const MyComponent: React.FC<Props> = ({
required,
optDefault='default'
}: Props) => (
<ul>
<li>required: {required}</li>
<li>optDefault: {optDefault}</li>
</ul>
)
ReactDOM.render(
<div>
<MyComponent
required='required'
optDefault='over written'
/>
<MyComponent
required='required'
/>
</div>,
document.getElementById('app')
);
But the problem with this solution is that if you forgot to provide default, a run time bug will result:
const MyComponent: React.FC<Props> = ({
required,
optDefault //='optDefault' //<--- if you forgot to provide default
}: Props) => (
<ul>
<li>required: {required}</li>
<li>optDefault: {optDefault}</li> {/* <-- result in bug */}
</ul>
)
A better solution is not using React.FC at all, simply rely on Typescript type inference:
type Props = {
required: string,
} & typeof defaultProps;
const defaultProps = {
optDefault: 'optDefault'
};
const MyComponent = (props: Props) => (
<ul>
<li>required: {props.required}</li>
<li>optDefault: {props.optDefault}</li>
</ul>
)
MyComponent.defaultProps = defaultProps
ReactDOM.render(
<div>
<MyComponent
required='required'
optDefault='over written'
/>
<MyComponent
required='required'
/>
</div>,
document.getElementById('app')
);
You can put this inside your component
static defaultProps: any;
After 2 hours of looking for solution... it's working.
If you want to define defaultProps
, your arrow function should look like:
export const CenterBox: React.SFC<CenterBoxProps> = props => {
(...)
};
Then you can define props like:
CenterBox.defaultProps = { someProp: true }
Note that React.SFC
is alias for React.StatelessComponent
.
I hope that this question (and answer) help somebody. Make sure that you have installed newest React typings.
I believe a better way than described in the React docs is simply to use Javascript / Typescript default arguments.
There's an answer here: https://stackoverflow.com/a/54569933/484190 but for convenience, here's an example:
import React, { FC } from "react";
interface CompProps {
x?: number;
y?: number;
}
const Comp: FC<CompProps> = ({ x = 10, y = 20 }) => {
return <div>{x}, {y}</div>;
}
export default Comp;
This will allow Typescript to know that you don't have to provide the prop, and also that it will never be "undefined" inside your component
For Functional Components as of React 16.7.0 the 'React.SFC' type is being deprecated in favour of 'React.FC
'.
type TFuncComp = React.FC<{ text: string }>
const FuncComp: TFuncComp = props => <strong>{props.text}</strong>
FuncComp.defaultProps = { text: 'Empty Text' }
Deprecation Warning in Source
FC (FunctionalComponent) Type in Source
And here's how it works for stateful functions in case others stumble on this. The key is declaring defaultProps as a static variable.
interface IBoxProps extends React.Props<IBoxProps> {
x?: number;
y?: number;
height?: number;
width?: number;
}
interface IBoxState {
visible?: boolean;
}
export default class DrawBox extends React.Component<IBoxProps, IBoxState> {
static defaultProps: IBoxProps;
constructor(props: IBoxProps) {
super(props);
}
...
}
DrawBox.defaultProps = {
x=0;
y=0;
height=10;
weight=10;
};