定义函数

函数的输入输出要进行类型的定义,函数的参数一旦定义好以后,输入多或者少都是会编译报错的,返回类型也必须跟定义的一致;

// 1
function fun(a: string, b: number): number {
   return parseInt(a + b);
}
// 2 这种写法只对右侧的匿名函数进行了类型定义,左侧的funs只能通过类型推断得出
const funs = function(a: string, b: number):number {
   return parseInt(a + b);
}
// 3 等号两侧都进行了类型定义
const funs: (a: string, b: number)=> number = function (a: string, b: number): number{
	return parseInt(a + b);
}
// 这里的 => 不要跟es6里的箭头函数混淆,ts里用于表示函数的定义,左边是输入类型,需要用括号括起来;右边是输出类型

可选参数和默认值

通过?可以指定可选参数,如下:

function fun(a: number, a2: string='2', b?: string):number {}

注意

  • 可选参数必需出现在必需参数的后面;
  • ts会把设置了默认值的参数当成是可选参数, 这样的可选参数不受前面的约束

剩余参数

可以通过es6展开操作符来指定剩余参数, 当前剩余参数只能是最后一个参数

function fun(array: any[], ...rest: any[]):any[]{}

用接口方式定义函数

通过这种方式 可以对函数表达式定义的函数 进行等号左侧的类型定义,保证了传入的参数和返回值类型不变

interface Func {
	(a: string, b: number): boolean;
}
let myFunc: Func;
myFunc = function (a: string, b: number):boolean {}

也可以使用含有泛型的接口来定义函数的形状

interface CreateArrayFunc {
   <T>(length: number, value: <T>): Array<T>
}
// 可以把泛型参数提到接口名上
// interface CreateArrayFunc<T> {
//    (length: number, value: <T>): Array<T>
// }

let createArray: CreateArrayFunc<any>;
createArray = function<T>(length: number, value: <T>): Array<T> {
   
}

重载

重载允许一个函数接受不同的数量或类型的参数时,作出不同的处理;
可以通过联合类型来实现不同的处理,但是表达起来不够精确。(例如如下方法,对参数反转,用联合类型无法表达清楚,传入的是数字类型,返回也是数字类型。)
通过重载,可以表达清晰;在写重载时,前几次都是定义,最后一个才是具体的函数实现。

// ts会按照定义顺序,自上而下匹配,如果多个函数定义有包含关系,需要优先把精确的定义写在前面。
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string
 {
    if (typeof x === 'number') {
       return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
       return x.split('').reverse().join('');
    }
 }