Encountering an error with the code below that seems unexpected. TypeScript is flagging rules[name]
as not being callable, which is true since it can be undefined
. Even after guarding against this case, the same error persists. The issue is elaborated in the code comments.
This expression is not callable.
Not all constituents of type '((value: string | number) => boolean) | undefined' are callable.
Type 'undefined' has no call signatures.ts(2349)
type FieldValues = Record<string, string | number>;
type FieldName<FormValues> = keyof FormValues;
type FormState<FormValues> = {
values: FormValues,
errors: Record<FieldName<FormValues>, boolean>,
focused: Record<FieldName<FormValues>, boolean>,
touched: Record<FieldName<FormValues>, boolean>,
dirty: Record<FieldName<FormValues>, boolean>,
isValid: boolean,
isDirty: boolean,
};
export function useForm<FormValues extends FieldValues> (
defaultValues: FormValues,
rules?: Partial<Record<FieldName<FormValues>, (value: string | number) => boolean>>,
) {
...
const validate = (name: FieldName<FormValues>, value: string | number) => {
// either if (rules && rules[names]) or if (rules && rules[name] instanceof Function)
// should narrow out undefined thus guaranteeing the correct call signature
if (rules && rules[name] instanceof Function) {
setFormState((prevFormState: FormState<FormValues>) => ({
...prevFormState,
errors: {
...prevFormState.errors,
[name]: rules[name](value),
},
isValid: isFormValid({
...prevFormState.errors,
[name]: rules[name](value),
}),
}))
}
}
...
}
A similar issue has been reported as a bug:
stackoverflow issue
Having trouble understanding the reported bug: i) does this fall under the same type of issue and ii) what is the workaround for this?
Edit: changed the title from 'Guarding for function in union type not working' to 'Guarding for undefined in union type not working' as it describes the problem more accurately.