Typescript 警告-无法调用其类型缺少调用签名的表达式

Typescript 警告-无法调用其类型缺少调用签名的表达式,typescript,typescript2.0,Typescript,Typescript2.0,我有以下代码: export interface IStartCreate1 { (desc?: string, opts?: IDescribeOpts, arr?: Array<string | IDescribeOpts | TCreateHook>, fn?: TCreateHook): void; tooLate?: boolean; } export interface IStartCreate2 { (opts?: IDescribeOpts, arr?:

我有以下代码:

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;
我收到以下错误消息:

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

我认为空数组将匹配
IStartCreate3


我已经看过其他带有类似错误信息的SO问题,但我无法理解这一个

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

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

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


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

从2017年开始,联合类型似乎不能有调用签名:

看起来很蹩脚

因此,我必须取消联合类型,并以不同的方式进行,如下所示:

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;
}
导出类型TArray=Array;
导出接口IStartCreate{
(描述:字符串| IDescribeOpts | TCreateHook | TArray,
选项?:idescribopts | TCreateHook | TArray,
arr?:TArray | TCreateHook,
):无效;
tooLate?:布尔值;
}

这似乎描述了这个问题:我同意,在这种情况下,这是为了方便用户,而不是为了类型安全,但我通常同意最好不要过载-最好创建不同的方法,每个方法都有特定的签名。我添加了一个描述联合类型不可“调用”的答案。
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;
}