是否可以为重载的函数签名创建类型别名?
例如,我有一个函数,例如:
function whenChanged(scope: ng.IScope, fn: ()=>void): ()=>void;
function whenChanged(fn: ()=>void, truthy:any): ()=>void;
function whenChanged(a,b): ()=>void {
//...
}
我想为该重载签名创建类型别名以节省重复,并在需要描述此函数类型的其他地方使用。
我试过了:
type WC1 = (scope: ng.IScope, fn: ()=>void) => ()=>void;
type WC2 = (fn: ()=>void, truthy:any) => ()=>void;
type WhenChanged = WC1 | WC2;
const whenChanged: WhenChanged = (a,b) => {
//...
};
但是尝试使用此函数时,我收到类似"无法调用类型缺少调用签名的表达式"的错误。
我无法在文档中看到有关类型别名函数重载的任何内容。
由于您已经拥有函数whenChanged
:
function whenChanged(scope: ng.IScope, fn: ()=>void): ()=>void;
function whenChanged(fn: ()=>void, truthy:any): ()=>void;
function whenChanged(a,b): ()=>void {
//...
}
获取其类型的类型别名的最简单方法是使用typeof
类型查询:
type WhenChanged = typeof whenChanged;
创建类型别名的下一个最直接的方法是使用重载的函数签名(这是您要查找的(:
type WhenChanged = {
(scope: ng.IScope, fn: () => void): () => void;
(fn: () => void, truthy: any): () => void;
}
(如果将鼠标悬停在编辑器中的typeof
定义上,您将在 Quickinfo 中看到这一点。 请注意,如果您不想使用interface
,则无需使用。
接下来你可以做的和你正在做的事情类似,但问题是重载是一个交叉点,而不是一个联合。 它既是签名:
type WC1 = (scope: ng.IScope, fn: ()=>void) => ()=>void;
type WC2 = (fn: ()=>void, truthy:any) => ()=>void;
type WhenChanged = WC1 & WC2; // and, not or
请注意,函数签名的交集不是可交换的,特别是因为它们表示重载。 这意味着以下类型在技术上并不相同:
type NotWhenChanged = WC2 & WC1; // different type
因为过载解析将以不同的顺序进行。
请注意,您不能调用类型WC1 | WC2
的函数,因为调用签名不同,编译器无法判断该函数是WC1
还是WC2
。
好的,你去吧。 希望对您有所帮助;祝你好运!
经过一番玩,事实证明答案是(至少部分(使用界面。这似乎有效:
interface WhenChanged {
(scope: ng.IScope, fn: ()=>void): ()=>void
(fn: ()=>void, truthy:any): ()=>void
}
const whenChanged: WhenChanged = (a,b) => {
//...
};
"无法调用类型缺少调用签名的表达式"意味着类型联合不可调用,您必须选择一种类型或另一种类型。
问题是,在您给出的示例中,您没有为a
和b
定义类型,因此编译器无法分辨实际使用了哪个WC1
和WC2
。如果更改whenChanged
的定义:
const whenChanged: WhenChanged = (a: ng.IScope, b: ()=>void) => {
return b;
};
现在,编译器知道它可以将whenChanged
的类型限制为WC1
,以便您可以安全地调用它。
如果你有一个变量而不是 const,并且whenChanged
可能是WC1
的,也可以以编译器无法分辨的方式WC2
,那么在调用它之前,你将不得不使用某种类型断言将类型限制为一个或另一个:
(whenChanged as WC1)(some_scope, some_fn);
或:
(whenChanged as WC2)(some_fn, some_truthy);
您不能做的是从whenChanged
中找出它包含的类型,以便使用适当的参数调用它。您必须从其他地方获取这些信息。