重载

在某些逻辑较复杂的情况下,函数可能有多组入参类型和返回值类型。

function func(foo: number, bar?: boolean): string | number {
  if (bar) {
    return String(foo);
  } else {
    return foo * 599;
  }
}

要想实现与入参关联的返回值类型,我们可以使用 TypeScript 提供的函数重载签名,将以上的例子使用重载改写。

function func(foo: number, bar: true): string;
function func(foo: number, bar?: false): number;
function func(foo: number, bar?: boolean): string | number {
  if (bar) {
    return String(foo);
  } else {
    return foo * 599;
  }
}

const res1 = func(599); // number
const res2 = func(599, true); // string
const res3 = func(599, false); // number

这里有一个需要注意的地方,拥有多个重载声明的函数在被调用时,是按照重载的声明顺序往下查找的。因此在第一个重载声明中,为了与逻辑中保持一致,即在 bar 为 true 时返回 string 类型,这里我们需要将第一个重载声明的 bar 声明为必选的字面量类型。

实际上,TypeScript 中的重载更像是伪重载,它只有一个具体实现,其重载体现在方法调用的签名上而非具体实现上。而在如 C++ 等语言中,重载体现在多个名称一致但入参不同的函数实现上,这才是更广义上的函数重载。