# 函数类型

函数类型

在 JavaScript 中,有两种常见的定义函数的方式——函数声明(Function Declaration)函数表达式(Function Expression)

在 js 中,定义一个函数有一下两种方式:

// 函数声明 命名函数
function add(x, y) { return x + y; }

// 函数表达式 匿名函数
let myAdd = function (x, y) { return x + y; };

函数声明

在 ts 中,同样可以使用,只不过需要对参数、返回值进行类型约束:

function add(x: number, y: number): number {
  return x + y
}

其中 x、y 必须是 number 类型,返回值也必须是 number 类型。

函数表达式

let fun = function add(x: number, y: number): number {
  return x + y
}

函数完整写法

let add: (x: number, y: number) => number = function (x: number, y: number): number {
  return x + y
}

函数参数可选

现在我们有一个函数:

let getName = function (x: string, y: string): string {
  return x + y
}
console.log(getName('你好,', '我是ed.'))

打印输出结果:

在这里插入图片描述

如果我们不想传递 y ,只传递 x 怎么办?很简单设置参数可选:

let getName = function (x: string, y?: string): string {
  return x + y
}
console.log(getName('我是ed.'))

我们用 ? 标识该参数可有可无。

打印结果:

在这里插入图片描述

因为我们只传了第一个参数,所以第一个参数打印成功,第二个参数没有传递,所以是 undefined。

但是要注意:需要注意的是,可选参数必须接在必需参数后面。换句话说,可选参数后面不允许再出现必需参数了。

默认参数

在 ES6 中,我们允许给函数的参数添加默认值,TypeScript 会将添加了默认值的参数识别为可选参数:

let getName = function (x: string = '我是ed.', y?: string): string {
  return x + y
}
console.log(getName())

设置 x 的默认参数为 “我是ed.”,调用方法的时候不传参,则直接使用默认参数。

此时就不受「可选参数必须接在必需参数后面」的限制了。

剩余参数

ES6 中,可以使用 ...rest 的方式获取函数中的剩余参数(rest 参数)。

// 剩余参数
function fun(a, ...args) {
    console.log(a, args);
}
fun(1, 2, 3, 4, 5, 6);

查看打印结果:

在这里插入图片描述

函数重载

重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。

可以理解成函数名称是一样的,但是形参不同的多个函数。

比如,我们需要实现一个函数 reverse,输入数字 123 的时候,输出反转的数字 321,输入字符串 'hello' 的时候,输出反转的字符串 'olleh'。

利用联合类型,我们可以这么实现:

function reverse(x: number | string): number | string | void {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

然而这样有一个缺点,就是不能够精确的表达,输入为数字的时候,输出也应该为数字,输入为字符串的时候,输出也应该为字符串。

这时,我们可以使用重载定义多个 reverse 的函数类型:

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | void {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

上例中,我们重复定义了多次函数 reverse,前几次都是函数定义,最后一次是函数实现。在编辑器的代码提示中,可以正确的看到前两个提示。

注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。

posted @ 2023-12-25 17:55  我是ed  阅读(5)  评论(0编辑  收藏  举报