TypeScript:我可以为重载的函数签名提供类型别名吗?



是否可以为重载的函数签名创建类型别名?

例如,我有一个函数,例如:

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) => {
//...
};

"无法调用类型缺少调用签名的表达式"意味着类型联合不可调用,您必须选择一种类型或另一种类型。

问题是,在您给出的示例中,您没有为ab定义类型,因此编译器无法分辨实际使用了哪个WC1WC2。如果更改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中找出它包含的类型,以便使用适当的参数调用它。您必须从其他地方获取这些信息。

最新更新