Problem
In the below example, it is expected that the value "DEFAULT"
will be substituted to optionalPropertyExample
when it has not been specified:
type Properties = Readonly<{
requiredPropertyExample: string;
optionalPropertyExample: string;
}>;
class Sample extends React.Component<Properties> {
private static defaultProps: Partial<Properties> = {
optionalPropertyExample: "DEFAULT"
};
public render(): ReactNode {
// ✓ No TypeScript errors
const optionalPropertyExample: string = this.props.optionalPropertyExample;
// ...
}
}
But, it we will not specify the optionalPropertyExample
when using the Sample
as component:
<Sample
requiredPropertyExample="Sample"
/>
we'll get the error:
TS2741: Property 'optionalPropertyExample' is missing in type ...'.
Well, it is because the optionalPropertyExample
is required on Properties
type. But will it be the solution if to make it optional?
type Properties = Readonly<{
requiredPropertyExample: string;
optionalPropertyExample?: string;
}>;
class Sample extends React.Component<Properties> {
private static defaultProps: Partial<Properties> = {
optionalPropertyExample: "DEFAULT"
};
public render(): ReactNode {
const optionalPropertyExample: string = this.props.optionalPropertyExample;
// ...
}
}
Now, we'll get the error
TS2322: Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.
in the render
method. Yes, thanks to defaultProps
the this.props.optionalPropertyExample
will not be undefined
but the problem is how to assure the TypeScript! Without any
, variable!
and other type safety cracks, off course.
Unacceptable solutions
Just use the Hooks API!
This question is focused on class components. The ones who are fine with hooks API hardly will read this topics.
Substitute the value on decomposing of the object
Easy, but not scalable. Assume that we have N methods method1
, method2
... methodN
using optionalPropertyExample
where N is the arbitrary large number.
type Properties = Readonly<{
requiredPropertyExample: string;
optionalPropertyExample?: string;
}>;
class Sample extends React.Component<Properties> {
private static defaultProps: Required<Pick<Properties, "optionalPropertyExample">> = {
optionalPropertyExample: "DEFAULT"
};
private method1(): ReactNode {
const optionalPropertyExample: string = this.props.optionalPropertyExample ?? "DEFAULT";
// ...
}
private method2(): ReactNode {
const optionalPropertyExample: string = this.props.optionalPropertyExample ?? "DEFAULT";
// ...
}
//
private methodN(): ReactNode {
const optionalPropertyExample: string = this.props.optionalPropertyExample ?? "DEFAULT";
// ...
}
public render(): ReactNode {
const optionalPropertyExample: string = this.props.optionalPropertyExample;
}
}
Now, we want to change the default value of optionalPropertyExample
. We need to find all "DEFAULT"
occurrences in the code and replace it. There is the risk to forget one of more occurrences or mix up something related.
Maybe we should refer to defaultProps
?
type Properties = Readonly<{
requiredPropertyExample: string;
optionalPropertyExample?: string;
}>;
class Sample extends React.Component<Properties> {
private static defaultProps: Required<Pick<Properties, "optionalPropertyExample">> = {
optionalPropertyExample: "DEFAULT"
};
private method1(): ReactNode {
const optionalPropertyExample: string = this.props.optionalPropertyExample ?? Sample.defaultProps.optionalPropertyExample;
// ...
}
private method2(): ReactNode {
const optionalPropertyExample: string = this.props.optionalPropertyExample ?? Sample.defaultProps.optionalPropertyExample;
// ...
}
//
private methodN(): ReactNode {
const optionalPropertyExample: string = this.props.optionalPropertyExample ?? Sample.defaultProps.optionalPropertyExample;
// ...
}
public render(): ReactNode {
const optionalPropertyExample: string = this.props.optionalPropertyExample ?? Sample.defaultProps.optionalPropertyExample;
}
}
Is it best that possible?
from Providing of default props in class components of React + TypeScript
No comments:
Post a Comment