函数

和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);   // 3add("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...