您现在的位置是:首页 > 编程 > 

【TypeScript】006

2025-07-26 20:42:11
【TypeScript】006 7、函数的类型 函数是 JavaScript 中的一等公民!函数声明在 JavaScript 中,有两种常见的定义函数的方式——函数声明(Function Declaration)和函数表达式(Function Expression):代码语言:javascript代码运行次数:0运行复制// 函数声明(Function Declaration) function

【TypeScript】006

7、函数的类型

函数是 JavaScript 中的一等公民!

函数声明

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

代码语言:javascript代码运行次数:0运行复制
// 函数声明(Function Declaration)
function sum(x, y) {
    return x + y;
}

// 函数表达式(Function Expression)
let mySum = function (x, y) {
    return x + y;
};

一个函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到,其中函数声明的类型定义较简单:

代码语言:javascript代码运行次数:0运行复制
function sum(x: number, y: number): number {
    return x + y;
}

注意,输入多余的(或者少于要求的)参数,是不被允许的

代码语言:javascript代码运行次数:0运行复制
function sum(x: number, y: number): number {
    return x + y;
}
sum(1, 2, );

// (4,1): error TS246: Supplied parameters do not match any signature of call target.
function sum(x: number, y: number): number {
    return x + y;
}
sum(1);

// (4,1): error TS246: Supplied parameters do not match any signature of call target.
函数表达式

如果要我们现在写一个对函数表达式(Function Expression)的定义,可能会写成这样:

代码语言:javascript代码运行次数:0运行复制
let mySum = function (x: number, y: number): number {
    return x + y;
};

这是可以通过编译的,不过事实上,上面的代码只对等号右侧的匿名函数进行了类型定义,而等号左边的 mySum,是通过赋值操作进行类型推论而推断出来的。如果需要我们手动给 mySum 添加类型,则应该是这样:

这么写看上去好麻烦呀!

代码语言:javascript代码运行次数:0运行复制
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
};

注意不要混淆了 TypeScript 中的 => 和 ES6 中的 =>

在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。

在 ES6 中,=> 叫做箭头函数,应用十分广泛,可以参考 ES6 中的箭头函数。

用接口定义函数的形状

形状?真的可以说是模板!下面的写法看上去像是一种封装!

我们也可以使用接口的方式来定义一个函数需要符合的形状:

代码语言:javascript代码运行次数:0运行复制
interface SearchFunc {
    (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    return source.search(subString) !== -1;
}

采用函数表达式|接口定义函数的方式时,对等号左侧进行类型限制,可以保证以后对函数名赋值时保证参数个数、参数类型、返回值类型不变。

可选参数

前面提到,输入多余的(或者少于要求的)参数,是不允许的。那么如何定义可选的参数呢?

与接口中的可选属性类似,我们用 ? 表示可选的参数:

代码语言:javascript代码运行次数:0运行复制
function buildame(firstame: string, lastame?: string) {
    if (lastame) {
        return firstame + ' ' + lastame;
    } else {
        return firstame;
    }
}
let tomcat = buildame('Tom', 'Cat');
let tom = buildame('Tom');

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

代码语言:javascript代码运行次数:0运行复制
function buildame(firstame?: string, lastame: string) {
    if (firstame) {
        return firstame + ' ' + lastame;
    } else {
        return lastame;
    }
}
let tomcat = buildame('Tom', 'Cat');
let tom = buildame(undefined, 'Tom');

// (1,40): error TS1016: A required parameter cannot follow an optional parameter.
参数默认值

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

代码语言:javascript代码运行次数:0运行复制
function buildame(firstame: string, lastame: string = 'Cat') {
    return firstame + ' ' + lastame;
}
let tomcat = buildame('Tom', 'Cat');
let tom = buildame('Tom');

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

代码语言:javascript代码运行次数:0运行复制
function buildame(firstame: string = 'Tom', lastame: string) {
    return firstame + ' ' + lastame;
}
let tomcat = buildame('Tom', 'Cat');
let cat = buildame(undefined, 'Cat');

关于默认参数,可以参考 ES6 中函数参数的默认值。

剩余参数

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

代码语言:javascript代码运行次数:0运行复制
function push(array, ...items) {
    items.forEach(function(item) {
        array.push(item);
    });
}

let a: any[] = [];
push(a, 1, 2, );

事实上,items 是一个数组。所以我们可以用数组的类型来定义它:

代码语言:javascript代码运行次数:0运行复制
function push(array: any[], ...items: any[]) {
    items.forEach(function(item) {
        array.push(item);
    });
}

let a = [];
push(a, 1, 2, );

注意,rest 参数只能是最后一个参数,关于 rest 参数,可以参考 ES6 中的 rest 参数。

重载

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

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

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

代码语言:javascript代码运行次数:0运行复制
function reverse(x: number | string): number | string | void {
    if (typeof x === 'number') {
        return umber(().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

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

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

看起来不是那么简洁啊!

代码语言:javascript代码运行次数:0运行复制
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | void {
    if (typeof x === 'number') {
        return umber(().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent 删除函数字符串typescriptfunctitring

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1197058.html

相关标签:无
上传时间: 2025-07-23 08:34:33

上一篇:【TypeScript】007

下一篇:【TypeScript】005

留言与评论(共有 10 条评论)
本站网友 青岛团购网
29分钟前 发表
error TS246
本站网友 叨客
21分钟前 发表
输入字符串 'hello' 的时候
本站网友 avxiu
14分钟前 发表
而等号左边的 mySum
本站网友 河南新安县
26分钟前 发表
换句话说
本站网友 袁弘离开唐人
0秒前 发表
number { return x + y; };这是可以通过编译的
本站网友 造纸产业发展政策
2分钟前 发表
number
本站网友 宝宝咳嗽食疗
14分钟前 发表
我们可以使用重载定义多个 reverse 的函数类型: 看起来不是那么简洁啊!代码语言:javascript代码运行次数:0运行复制function reverse(x
本站网友 南京清吧
27分钟前 发表
error TS246
本站网友 开出
20分钟前 发表
要在 TypeScript 中对其进行约束