0
votes

executing below line gives me Error:(288, 25) TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'CreateValidateObjectType | ((param: string) => CreateValidateObjectType)' has no compatible call signatures.

validationMap[FORM_ELEMENTS_NAMES.LAST_NAME_INPUT]('aaaa')

Here is the validationMap and its type

type ValidationMapType = {
  [key: string]: CreateValidateObjectType | ((param: string) => CreateValidateObjectType);
};

const validationMap: ValidationMapType = {
  [FORM_ELEMENTS_NAMES.FIRST_NAME_INPUT]: createValidationObject({
    required: true,
    minLength: 2,
    maxLength: 25,
  }),
  [FORM_ELEMENTS_NAMES.LAST_NAME_INPUT]: (param: string) => createValidationObject({
    required: true,
    minLength: 2,
    maxLength: 25,
  })
}

Calling validationMap not as a function is not giving me any errors.

1

1 Answers

0
votes

You didn't tell use what CreateValidateObjectType is defined as, but from the error, i assume it's not a function. Since it's not a function, when you do this:

validationMap[FORM_ELEMENTS_NAMES.FIRST_NAME_INPUT]

You may or may not get a function. But your code assume it's always a function, because you're immediately and unconditionally calling it:

validationMap[FORM_ELEMENTS_NAMES.FIRST_NAME_INPUT]('aaaa')

Typescript is pointing out that, per the types you've defined, you have to check if it's a function first. For example:

const validation = validationMap[FORM_ELEMENTS_NAMES.FIRST_NAME_INPUT];
let result: CreateValidateObjectType;
if (typeof validation === 'function') {
  result = validation('aaaa');
} else {
  result = validation;
}

If you know ahead of time which properties will be functions and which ones will not, then you could drop the use of the index type, and that way typescript will be able to know "ah yes, the LAST_NAME_INPUT property; this is a function".

const validationMap = { // <--- no longer an index type
  [FORM_ELEMENTS_NAMES.FIRST_NAME_INPUT]: createValidationObject({
    required: true,
    minLength: 2,
    maxLength: 25,
  }),
  [FORM_ELEMENTS_NAMES.LAST_NAME_INPUT]: (param: string) => createValidationObject({
    required: true,
    minLength: 2,
    maxLength: 25,
  })
}

That will mean you don't need to check, but it also means you can't arbitrarily add/remove keys at runtime, like an index type allows.