“不畏惧,不将就,未来的日子好好努力”——大家好!我是小芝麻?
函数是JavaScript应用程序的基础。 它帮助你实现抽象层,模拟类,信息隐藏和模块。
在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义行为的地方。 TypeScript为JavaScript函数添加了额外的功能,让我们可以更容易地使用。
和JavaScript一样,TypeScript函数可以创建有名字的函数和匿名函数。
1、书写函数的类型
函数类型包含两部分: 参数类型 和 返回值类型
- 参数类型
let myAdd: (x: number, y: number) => number = 
    function(x: number, y: number): number { return x + y; };
    
// 只要参数类型是匹配的,那么就认为它是有效的函数类型,而不在乎参数名是否正确。
let myAdd: (baseValue: number, increment: number) => number = 
    function(x: number, y: number): number { return x + y; };
复制代码- 返回值类型
// 没有返回值
function hello(name: string): void {
  console.log('hello', name)
  return undefined
}
hello('金色小芝麻')
复制代码在函数和返回值类型之前使用( =>)符号,使之清晰明了。如果函数没有返回任何值,也必须指定返回值类型为 void而不能留空。

2、函数的参数
2.1 可选参数
在 TS 中函数的形参和实参个数必须一样,不一样就要配置可选参数,而且可选参数必须是最后一个参数
function print(name: string, age: number) {}
print('金色小芝麻') // ERROR 应有 2 个参数,但获得 1 个。未提供 "age" 的自变量。
print('金色小芝麻', 18) // YES 
print('金色小芝麻', 18, true) // ERROR 应有 2 个参数,但获得 3 个。
复制代码
JavaScript里,每个参数都是可选的,可传可不传。 没传参的时候,它的值就是undefined。 在TypeScript里我们可以在参数名旁使用 ?实现可选参数的功能。 例如:
// 可选参数必须跟在必须参数后面, 如果想让 name 参数可选,age 参数必选,就需要调整参数位置
function print(name: string, age?: number): void {}
print('金色小芝麻') // YES
print('金色小芝麻', 18) // YES
print('金色小芝麻', 18, true) // ERROR 应有 1-2 个参数,但获得 3 个。
复制代码参数 age 有number与undefined两种可能
2.2 默认参数
- 在TypeScript里,也可以为参数提供一个默认值当用户没有传递这个参数或传递的值是undefined时。 它们叫做有默认初始化值的参数。
function print(name: string, age: number = 18 ): void {}
print('金色小芝麻') // YES
print('金色小芝麻', 11) // YES
print('金色小芝麻', 11, true) // ERROR 应有 1-2 个参数,但获得 3 个。
复制代码在所有必须参数后面的带默认初始化的参数都是可选的,与可选参数一样,在调用函数的时候可以省略。
- 可选参数与末尾的默认参数的参数类型是一样的,都是
(name: string, age?: number) => void
复制代码与普通可选参数不同的是,带默认值的参数不需要放在必须参数的后面。
- 如果带默认值的参数出现在必须参数前面,必须明确的传入 undefined值来获得默认值。
function print(name: string = '金色小芝麻', age: number): void {
    console.log(name)
}
print('金色小芝麻') // ERROR 应有 2 个参数,但获得 1 个。未提供 "age" 的自变量
print('金色小芝麻', 18) // YES '金色小芝麻'
print(undefined, 18) // YES '金色小芝麻'
复制代码2.3 剩余参数
必要参数,默认参数和可选参数有个共同点:它们表示某一个参数。 有时,我们想同时操作多个参数,或者你并不知道会有多少参数传递进来。 在JavaScript里,你可以使用 arguments来访问所有传入的参数。
在TypeScript里,我们可以把所有参数收集到一个变量里:
function buildName(firstName: string, ...restOfName: string[]) { 
    return firstName + " " + restOfName.join(" "); 
} 
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
// employeeName 的类型: (fname: string, ...rest: string[]) => string
复制代码剩余参数会被当做 个数不限的可选参数。 可以一个都没有,同样也可以有任意个。 编译器创建参数数组,名字是我们在省略号( ...)后面给定的名字,我们可以在函数体内使用这个数组。
3、函数重载
- 函数重载或方法重载是使用相同名称和不同参数数量或类型创建多个方法的一种能力。
let obj: any = {};
function attr(val: number): void
function attr(val: string): void
function attr(val: any): void{
  if(typeof val === 'string'){
    obj.name = val;
  }else if(typeof val === 'number'){
    obj.age = val;
  }
}
attr('123'); // YES
attr(10); // YES
attr(true); // ERROR 
//`function  attr(val: any): void`并不是重载列表的一部分,因此这里只有两个重载:
// + 一个是接收数字另一个接收字符串。 以其它参数调用 `attr`会产生错误。
复制代码它查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。
注意,function  attr(val: any): void并不是重载列表的一部分,因此这里只有两个重载:一个是接收数字另一个接收字符串。 以其它参数调用 attr会产生错误。
参考文献
[1]. TypeScript中文网























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
