函数
和 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…