typescript函数对象-基于TypeScript的函数重载

2023-08-23 0 3,598 百度已收录

功能

与 JavaScript 一样typescript函数对象,TypeScript 函数可以创建命名函数和匿名函数。

// 具名函数
function add (x, y) {
    return x + y;
}
// 匿名函数
let myAdd = function (x, y) { return x + y; }
// 表达式中的 具名函数 在javascript中存在这样一个限制,表达式中的 具名函数只识别为匿名函数 ,而忽略它的函数名
let fn = function add (x, y) { return x + y; }

定义函数的类型

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

注意:为每个参数添加类型后,不需要为函数本身添加返回值类型,因为 TypeScript 可以根据返回语句手动推断返回值类型

typescript函数对象-基于TypeScript的函数重载

函数重载

由于JavaScript是动态语言,我们一般会使用不同类型的参数来调用同一个函数,函数会根据不同的参数返回不同类型的调用结果:

function add (x, y) {
    return x + y;
}
add(1, 2);   // 3
add("1", "2");  // "12"

上述代码在 JS 环境中运行没有问题,而如果在 TypeScript 环境中且 TypeScript 编译器启用了 noImplicitAny(将 TypeScript 从可选类型语言转换为强制类型验证语言)配置项,则上述代码会提示出现以下错误消息:

Parameter 'x' implicitly has an 'any' type.
Parameter 'y' implicitly has an 'any' type.

此信息告诉我们参数 x 和参数 y 隐式具有 any 类型。 为了解决这个问题,我们可以为参数设置一个类型。由于我们希望add函数同时支持字符串和数字类型,所以我们可以定义一个字符串|数字联合类型

function add (x: number | string, y: number | string) {
    if (typeof x === 'string' || typeof y === 'string') {
        return x.toString() + y.toString();
    }
    return x + y;
}

设置关节类型后,之前的错误信息消失,然后下一步:

let result = add('hearts', 'spades');
result.split(' ');

我们贸然以为结果类型是string,然后就可以正常对string对象使用split方法了。 结果又出现了新问题typescript函数对象,提示number类型对象上不存在split属性。

Property 'split' does not exist on type 'string | number'.  
Property 'split' does not exist on type 'number'.

怎么处理呢?

在这种情况下,可以使用函数重载。 可以为同一个函数提供多个函数类型定义以进行函数重载(相同的函数名称、不同数量或类型的参数、或相同数量但参数顺序不同的参数)。

如何定义呢?

定义函数重载需要定义重载签名和实现签名

重载签名定义了函数的实际参数和返回类型,并且没有函数体。

一个函数可以有多个重载签名:主要是为了准确显示函数的输入和输出,对应调用函数的不同形式。

据悉,实现签名还有参数类型和返回类型,还有实现函数体,并且只能有一个实现签名。

签名的实现主要是全量定义所有的输入输出类型,避免TS编译错误。 签名的实现就是整个函数实现的整个逻辑。

喜欢:

type Types = number | string;
// 重载签名
function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: string, y: number): string;
function add(x: number, y: string): string;
function add(x: Types, y: Types) {
    if (typeof x === 'string' || typeof y === 'string') {
        return x.toString() + y.toString();
    }
    return x + y;
}
const result = add('hearts', ' spades');
result.split(' ');

编译成功,编译结果如下:

typescript函数对象-基于TypeScript的函数重载

上面定义了 4 个重载签名和 1 个实现签名。

注意:当 TypeScript 编译器处理函数重载时,它会查找重载列表并尝试使用第一个重载定义。 如果匹配就使用它。 因此,在定义重载时,请务必将最精确的定义放在顶部。

其他:

从编译结果可以看出,JavaScript作为动态语言,不存在函数重载这个词。 原因如下:

由于在语言层面很难手动重载,利用其动态特性,我们可以在代码中自动检测输入参数的类型,或者通过arguments获取参数的个数,从而可以根据不同的输入执行不同的操作参数。

参考

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 typescript typescript函数对象-基于TypeScript的函数重载 https://www.wkzy.net/game/143181.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务