【问题标题】:Warning - Cannot invoke an expression whose type lacks a call signature警告 - 无法调用其类型缺少调用签名的表达式
【发布时间】:2018-05-09 15:32:07
【问题描述】:

我有以下代码:

export interface IStartCreate1 {
  (desc?: string, opts?: IDescribeOpts, arr?: Array<string | IDescribeOpts | TCreateHook>, fn?: TCreateHook): void;
  tooLate?: boolean;
}

export interface IStartCreate2 {
  (opts?: IDescribeOpts, arr?: Array<string | IDescribeOpts | TCreateHook>, fn?: TCreateHook): void;
  tooLate?: boolean;
}

export interface IStartCreate3 {
  (arr?: Array<string | IDescribeOpts | TCreateHook>, fn?: TCreateHook): void;
  tooLate?: boolean;
}

export interface IStartCreate4 {
  (fn: TCreateHook): void;
  tooLate?: boolean;
}

export type IStartCreate = IStartCreate1 | IStartCreate2 | IStartCreate3 | IStartCreate4;

然后我有一个像这样的对象:

const v = {
  create: function(){} as IStartCreate
} 

v.create([]);

我收到此错误消息:

无法调用类型缺少调用签名的表达式。

我认为空数组会匹配 IStartCreate3

我查看了其他带有类似错误消息的 SO 问题,但我无法弄清楚这一点!

【问题讨论】:

标签: typescript typescript2.0


【解决方案1】:

了解您想要实现的目标会很有帮助。一般来说,这似乎是一个极其复杂的类型声明,很可能会导致问题。

您对IStartCreate 的声明表明它是要么 IStartCreate1 IStartCreate2 或3,但我们不知道是哪个。因此,您将只能访问存在于IStartCreate1IStartCreate2IStartCreate3所有 中的成员/签名(换句话说,只有tooLate)。您要查找的方法签名并不在所有这些中。

如果您确定v.create 实际上实现了IStartCreate3,则可以执行(v.create as IStartCreate3)([]),但如果它被证明是不同的类型,则会导致运行时错误。

一般来说,函数重载在 TypeScript 中不是特别好用,我通常会尽量避免这样做。

【讨论】:

  • 我同意,在这种情况下,这是为了用户方便,而不是类型安全,但我通常同意最好不要重载 - 最好创建不同的方法,每个方法都有特定的签名。我添加了一个描述联合类型不是“可调用”的答案。
【解决方案2】:

截至 2017 年,联合类型似乎不能有调用签名:

https://github.com/Microsoft/TypeScript/issues/7294

看起来很蹩脚。

所以我不得不取消联合类型并以不同的方式进行操作,如下所示:

export type TArray = Array<string | IDescribeOpts | TCreateHook>;

export interface IStartCreate {
  (desc: string | IDescribeOpts | TCreateHook | TArray,
   opts?: IDescribeOpts | TCreateHook | TArray,
   arr?: TArray | TCreateHook,
   ): void;
  tooLate?: boolean;
}

【讨论】:

    猜你喜欢
    • 2017-12-19
    • 2017-07-14
    • 2020-02-07
    • 1970-01-01
    • 2019-01-05
    • 2023-03-20
    • 2017-09-01
    • 2021-02-06
    • 2017-03-17
    相关资源
    最近更新 更多