【问题标题】:TypeScript Cannot invoke an expression whose type lacks a call signatureTypeScript 无法调用类型缺少调用签名的表达式
【发布时间】:2021-02-06 13:55:22
【问题描述】:

在下面执行给我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')

这是validationMap 及其类型

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,
  })
}

不作为函数调用validationMap 不会给我任何错误。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您没有告诉 use CreateValidateObjectType 的定义是什么,但从错误来看,我认为它不是一个函数。由于它不是一个函数,当你这样做时:

    validationMap[FORM_ELEMENTS_NAMES.FIRST_NAME_INPUT]
    

    您可能会或可能不会获得功能。但是您的代码假定它始终是一个函数,因为您会立即无条件地调用它:

    validationMap[FORM_ELEMENTS_NAMES.FIRST_NAME_INPUT]('aaaa')
    

    Typescript 指出,根据您定义的类型,您必须先检查它是否是一个函数。例如:

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

    如果你提前知道哪些属性是函数,哪些不是,那么你可以放弃使用索引类型,这样打字稿就可以知道“啊,是的,LAST_NAME_INPUT 属性;这是一个函数”。

    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,
      })
    }
    

    这意味着您不需要检查,但这也意味着您不能像索引类型允许的那样在运行时任意添加/删除键。

    【讨论】:

    • 谢谢,据我了解ValidationMapType 中的联合不会帮助我在不检查其类型的情况下使用validationMap
    • 既然你的联合说属性可能是函数也可能不是函数,那么你需要在调用它之前检查类型。如果您知道它们始终是函数,那么您可以将类型更改为这样说,然后您就不需要检查了。
    • 非常抱歉!我在复制validationMap 的内容时出错了。当前版本是否有任何更改?
    • 它有助于突出显示您有一些功能和一些非功能,但从类型和类型错误中已经很清楚了。既然你不知道你是否有一个函数,那么你就不能调用它。在 javascript 中,当您尝试运行代码时,它可能会引发 TypeError。在 typescript 中,当您尝试编译代码时会收到通知。
    • @akoko 我在我的答案的额外部分中进行了编辑。如果你提前知道所有类型,你也许可以去掉索引类型,然后地图的每个属性都是单一类型而不是联合
    猜你喜欢
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    • 2019-09-10
    • 2018-12-25
    • 1970-01-01
    • 2015-08-26
    相关资源
    最近更新 更多