我有以下代码:
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问题,我无法想出这个问题!
答案 0 :(得分: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;
}
答案 1 :(得分:1)
了解您要实现的目标会很有帮助。一般来说,这似乎是一个非常复杂的类型声明,可能会导致问题。
您对IStartCreate
的声明声明它 或 IStartCreate1
或3,但我们不是知道哪个。因此,您只能访问IStartCreate2
,IStartCreate1
和IStartCreate2
的所有中的成员/签名(换句话说,仅IStartCreate3
1}})。您正在寻找的方法签名不是全部。
如果您确定tooLate
实际上实现了v.create
,则可以执行IStartCreate3
,但如果结果是不同的类型,则会导致运行时错误。
一般来说,函数重载在TypeScript中效果不佳,我通常会尽量避免这样做。