I’m new with Typescript and JavaScript and I’m not sure how to solve a situation on my React project.
I have this component below, but my onChange()
line is not compiling. I receive a message saying this:
Type '((value: boolean) => void) | undefined' is not assignable to type '(value: boolean) => void'.
Type 'undefined' is not assignable to type '(value: boolean) => void'.ts(2322)
ISelectUnselectAll.ts(3, 3): The expected type comes from property 'onChange' which is declared here on type 'IntrinsicAttributes & ISelectUnselectAll'
<SelectUnselectAll
value={selectUnselectAll}
disabled={!totalsStore.parsedList.length}
onChange={onSelectUnselectAll}
mode={'MENU'}
/>}
Actually I think the problem is because my onSelectUnselectAll
function is coming by props from an interface when this function is optional. But I don’t know how to solve it.
export interface IExtraButtonsHeaderInvoiceTotals {
onSelectUnselectAll?: (value: boolean) => void;
If I remove the ?
the code compiles fine, but I can’t remove the ?
.
I appreciate any help
3
Answers
Thanks, guys.
The simplest solution was to check if my function is defined before rendering the component. The code looked like this:
It's working fine now.
Typescript purpose is to help with code maintenance and also to prevent possible errors that could happen in your application, that’s why that error pops up,
ISelectUnselectAll
is a contract which dictates exactly what you can pass to a your component, in that case, that contract says,onChange
cannot be undefined, for whatever reason.When you add
?
to a parameter it becomes possibly undefined and as you can see, the error says((value: boolean) => void) | undefined)
is not assignable to(value: boolean) => void
, that means that theISelectUnselectAll
parameteronChange
should always be defined.To solve this you could verify if the parameter exists before executing it, or remove
?
making it a obligatory param and making sure thatonSelectUnselectAll
always is a function.Also, you can simply add a ternary if, if your
ESlint
rules allow it:Also you could change the interface
ISelectUnselectAll
and letonChange
be undefinedYou should decide what to do when it is undefined, and handle that case.
Maybe the intent behind the original interface is that, if no function is provided, nothing is done, in which case the following should be correct. Here the function is passed if defined, and otherwise it is replaced by a default that does nothing.
Here is a working example.
An alternative you should consider would be to have the default function log an error or throw an exception.