关于typescript:TypeScript基础之函数重载

8次阅读

共计 2199 个字符,预计需要花费 6 分钟才能阅读完成。

函数

和 JavaScript 一样,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 能依据返回语句主动推断出返回值类型

函数重载

因为 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 函数同时反对 string 和 number 类型,因而咱们能够定义一个 string | number 联结类型

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(' ');

咱们想当然的认为 result 类型为 string,而后就能够失常应用字符串对象上的 split 办法,后果又呈现了新问题,提醒 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(' ');

编译胜利,编译后果如下:

以上定义了 4 个重载签名和一个实现签名。
须要留神的是:当 TypeScript 编译器处理函数重载时,它会查找重载列表,尝试应用第一个重载定义。如果匹配的话就应用这个。因而,在定义重载的时候,肯定要把最准确的定义放在最后面。

其余:
从编译后后果能够看出 JavaScript 作为动静语言,是没有函数重载这一说法的。起因如下:

  • 参数没有类型的辨别;
  • 对参数个数也没有查看

既然语言层面无奈主动进行重载,但借助其动静的个性,咱们能够在代码中手动查看入参的类型,或者通过 arguments 获取到参数个数,从而实现依据不同的入参做不同的操作。

参考资料

https://www.tslang.cn/docs/ha…
https://cloud.tencent.com/dev…
https://cloud.tencent.com/dev…

正文完
 0