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

jsd*_*sdw 2 typescript

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

例如,我有一个类似的功能:

function whenChanged(scope: ng.IScope, fn: ()=>void): ()=>void;
function whenChanged(fn: ()=>void, truthy:any): ()=>void;
function whenChanged(a,b): ()=>void {
    //...
}
Run Code Online (Sandbox Code Playgroud)

我想为重载的签名创建类型别名以节省重复,并在我需要描述此函数类型的其他地方使用。

我试过:

type WC1 = (scope: ng.IScope, fn: ()=>void) => ()=>void;
type WC2 = (fn: ()=>void, truthy:any) => ()=>void;
type WhenChanged = WC1 | WC2;

const whenChanged: WhenChanged = (a,b) => {
    //...
};
Run Code Online (Sandbox Code Playgroud)

但是尝试使用此函数时,我收到了“无法调用类型缺少调用签名的表达式”之类的错误。

我无法在文档中看到任何关于类型别名函数重载的内容。

jca*_*alz 6

既然你已经有了这个功能whenChanged

function whenChanged(scope: ng.IScope, fn: ()=>void): ()=>void;
function whenChanged(fn: ()=>void, truthy:any): ()=>void;
function whenChanged(a,b): ()=>void {
    //...
}
Run Code Online (Sandbox Code Playgroud)

为其类型获取类型别名的最简单方法是使用typeof 类型查询

type WhenChanged = typeof whenChanged;
Run Code Online (Sandbox Code Playgroud)

创建类型别名的下一个最直接的方法是使用重载函数签名(这正是您要找的):

type WhenChanged = {
  (scope: ng.IScope, fn: () => void): () => void;
  (fn: () => void, truthy: any): () => void;
}
Run Code Online (Sandbox Code Playgroud)

(如果您将鼠标悬停typeof在编辑器中的定义上,您将在 quickinfo 中看到。)请注意,interface如果您不想,则不需要使用 an 。


您可以做的下一件事与您正在做的类似,但问题是重载是一个交集,而不是一个联合。它是两个签名:

type WC1 = (scope: ng.IScope, fn: ()=>void) => ()=>void;
type WC2 = (fn: ()=>void, truthy:any) => ()=>void;
type WhenChanged = WC1 & WC2; // and, not or
Run Code Online (Sandbox Code Playgroud)

注意函数签名的交集不是可交换的,特别是因为它们代表重载。这意味着以下类型在技术上并不相同:

type NotWhenChanged = WC2 & WC1; // different type
Run Code Online (Sandbox Code Playgroud)

因为重载决议将以不同的顺序发生。

请注意,您不能调用类型为 的函数,WC1 | WC2因为调用签名不同,编译器无法判断该函数是WC1还是WC2


好的,你去。希望能帮助到你; 祝你好运!