I have a React Component that takes up an object which returns the input component to be rendered. But right now there is no strict type checking and that is the problem. Check the example below:
const FieldRenderer = (fieldProps: any) => {
// implementation here to be ignored
}
const fieldProps = {
id: 'gender',
label: 'Gender',
type: 'dropdown',
options: ['Male', 'Female']
}
<FieldRenderer fieldProps={fieldProps}/>
But the problem here is that even if you pass something like checked: true (which is applicable to a checkbox) or maxLength: 100 (which is for a textbox) the component won’t show an error and I want all the other properties to be typed according to the type property in the object.
Note: There is one problem though, the props are passed in the same way in the entire code base so I won’t be able to change it, but need to have a type check in place.
I need the following to be true
const FieldRenderer = (fieldProps: SomeTypehere) => {
// implementation here to be ignored
}
const fieldProps = {
id: 'gender',
label: 'Gender',
type: 'dropdown',
checked: true
}
<FieldRenderer fieldProps={fieldProps}/> // Error here as dropdown doesn't need a checked property but also needs a options property
Thanks in advance for the help !
2
Answers
You can use a discriminated union for the type of
fieldProps
(in this case, usingtype
as the discriminant):Notice that the type of
type
isn’tstring
, it’s the string literal type"checkbox"
for the checkbox props or"dropdown"
for the dropdown props.It works best when you’re providing the props inline, because you don’t have to provide an explicit type (or an
as const
):…but you can also do it with explicit types:
…or with
as const
:Playground link
The simplest solution is to just give the props a union type: