Say you define your component like so:
interface IProps {
req: string;
defaulted: string;
}
class Comp extends React.Component<IProps, void> {
static defaultProps = {
defaulted: 'test',
};
render() {
const { defaulted } = this.props;
return (
<span>{defaulted.toUpperCase()}</span>
);
}
}
when you want to use it, TypeScript wants the defaulted
prop from you, even though it's defined in defaultProps
:
<Comp req="something" /> // ERROR: TypeScript: prop 'defaulted' is required
However, if you define the props interface like so:
interface IProps {
req: string;
defaulted?: string; // note the ? here
}
then you cannot use it in:
render() {
const { defaulted } = this.props; // ERROR: prop 'defaulted' possibly undefined
return (
<span>{defaulted.toUpperCase()}</span>
);
}
How to define the IProps, defaultProps and component correctly so the types make sense?
EDIT:
I'm using the strictNullChecks
flag.
I have an example with the following code (ComponentBase is just my wrapper around React.Component).
Edit: updated code to work with 'strictNullChecks' setting
interface IExampleProps {
name: string;
otherPerson?: string;
}
/**
* Class with props with default values
*
* @class Example
* @extends {ComponentBase<IComponentBaseSubProps, {}>}
*/
export class Example extends ComponentBase<IExampleProps, {}> {
public static defaultProps: IExampleProps = {
otherPerson: "Simon",
name: "Johnny"
};
constructor(props: IExampleProps) {
super(props);
}
public render(): JSX.Element {
const person: string = this.props.otherPerson === undefined ? "" : this.props.otherPerson;
return(
<div>
<h1><small>Message by ComponentBaseSub: Hello {this.props.name} and {person} </small></h1>
</div>
);
}
}
I have no issues using Visual Studio Code, TypeScript 2.0.3, TSLint 0.5.39.
Even simpler is
<span>{(defaulted as string).toUpperCase()}</span>
Works the same way with properties. If Foo
requires the barProp
property but Parent
does not and gets it through defaultProps
, Parent
's render method can do
<Foo barProp={this.props.barProp as string} />
If you know for sure the prop will have a default value, you can use the null assertion type operator, like this:
render() {
const { defaulted } = this.props;
return (
<span>{defaulted!.toUpperCase()}</span>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With