Reputation: 600
I am getting an error with PropTypes. The Props are:
type FieldTypes = 'dropdown' | 'checkbox';
type PluginDropdownData = {
label: string;
value: string;
};
type PluginManifestObject = {
label: string;
type: FieldTypes;
data: Array<PluginDropdownData> | Array<string>;
mandatory: boolean;
};
{
manifestObject: PluginManifestObject
objectKey: string;
handleValueChange: (label: string, value: string | boolean) => void;
initialValue: string | boolean;
}
This is my solution:
ComponentA.propTypes = {
manifestObject: PropTypes.shape({
label: PropTypes.string.isRequired,
type: PropTypes.oneOf(['dropdown', 'checkbox']).isRequired,
data: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
})),
PropTypes.arrayOf(PropTypes.string),
]).isRequired,
mandatory: PropTypes.bool.isRequired,
}).isRequired,,
objectKey: PropTypes.string.isRequired,
handleValueChange: PropTypes.func.isRequired,
initialValue: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool,
]).isRequired,
};
But I am getting 2 errors:
Type 'Validator<InferProps<{ label: Validator<string>; type: Validator<string>; data: Validator<(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[] | (string | ... 1 more ... | undefined)[]>; mandatory: Validator<...>; }>>' is not assignable to type 'Validator<PluginManifestObject>'.
Type 'InferProps<{ label: Validator<string>; type: Validator<string>; data: Validator<(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[] | (string | ... 1 more ... | undefined)[]>; mandatory: Validator<...>; }>' is not assignable to type 'PluginManifestObject'.
Types of property 'type' are incompatible.
Type 'string' is not assignable to type 'FieldTypes'.ts(2322)
(property) manifestObject?: React.Validator<PluginManifestObject> | undefined
The above error is fixed by aleksxor answer but there is still one error, i.e.
Type 'Validator<InferProps<{ label: Validator<string>; type: Validator<"input" | "dropdown" | "checkbox" | "date" | "radio" | "range">; data: Validator<(InferProps<{ label: Validator<string>; value: Validator<...>; }> | null | undefined)[] | (string | ... 1 more ... | undefined)[]>; mandatory: Validator<...>; }>>' is not assignable to type 'Validator<PluginManifestObject>'.
Type 'InferProps<{ label: Validator<string>; type: Validator<"input" | "dropdown" | "checkbox" | "date" | "radio" | "range">; data: Validator<(InferProps<{ label: Validator<string>; value: Validator<...>; }> | null | undefined)[] | (string | ... 1 more ... | undefined)[]>; mandatory: Validator<...>; }>' is not assignable to type 'PluginManifestObject'.
Types of property 'data' are incompatible.
Type '(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[] | (string | null | undefined)[]' is not assignable to type 'string[] | PluginDropdownData[]'.
Type '(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[]' is not assignable to type 'string[] | PluginDropdownData[]'.
Type '(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[]' is not assignable to type 'string[]'.
Type 'InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.ts(2322)
(property) manifestObject?: React.Validator<PluginManifestObject> | undefined
I am not sure what I am missing here. Can someone please help me with this?
Thanks
Upvotes: 1
Views: 915
Reputation: 8380
The problem is you're passing non-readonly array to the oneOf
validator. And the values of non-readonly array are inferred as string
type. The solution is pretty simple. Just pass it readonly tuple:
...
type: PropTypes.oneOf(['dropdown', 'checkbox'] as const).isRequired,
...
Updated answer to address the second error.
To match the type: data: Array<PluginDropdownData> | Array<string>
you have to define your propTypes as:
...
data: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
}).isRequired),
PropTypes.arrayOf(PropTypes.string.isRequired),
]).isRequired,
Notice that if you want the array to pass the validation you have to declare it's elements as isRequired
. If you're not planning to make them isRequired
you have to add | null | undefined
to array's item type. For example those two definitions pass without error:
type PluginManifestObject = {
...
data: Array<PluginDropdownData | undefined | null> | Array<string | undefined | null>
...
}
...
data: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
})),
PropTypes.arrayOf(PropTypes.string),
]).isRequired,
...
Upvotes: 1