函数声明

我们知道,在JavaScript中,函数的声明有两种方式,一种是函数声明,另一种是函数表达式。

  1. function Fn (x, y) {
  2. return x + y;
  3. }
  4. let myFun = function (x, y) {
  5. return x + y;
  6. }

一个函数有输入和输出,要在TypeScript中进行约束,要考虑输入和输出,都要进行类型定义.

  1. function Fn(x:number, y:number):number {
  2. return x + y;
  3. }
  4. 分析
  5. 函数Fn,接收两个参数,都必须是number类型,输出值也必须是number类型

函数表达式

如果我们写一个简单的函数表达式,可以去这样写:

  1. let myFn = function (x: number, y: number): number {
  2. return x + y;
  3. }

这样也是可以通过编译的,不过事实上,上面的代码只是对等号右侧测匿名函数进行了类型的顶底,而等号左边的myFn函数并没有进行定义,只是根据类型推论而推断出来的,如果我们需要添加,可以这样去添加:

  1. let myFn: (x: number, y: number) => number = function (x: number, y: number): number {
  2. return x + y;
  3. }

这里的=>和es6中的=>不一样,这里是用来表示函数的定义.

用接口定义函数的形状

我们也可以使用接口的方式来定义一个需要符合的形状:

  1. interface Func {
  2. (x: string, y: any): boolean
  3. }
  4. let myFunc: Func = function (x: string, y:any) {
  5. return y > Number(x) ? true : false;
  6. }

采用函数表达式和接口定义函数类型时,对等号左边进行类型的限制,可以保证以后对函数名赋值时保证参数个数,参数类型,返回值保持不变。

可选参数

上面说到,在接口中定义好函数形状后,参数必须保持一致,不可以多也不可以少,那么如何定义参数可选呢?其实与接口定义可选属性类似,用?表示可选参数,注意,可选参数后面不能出现必选参数

  1. let myFn = function (x: number, y?: number): number {
  2. if(y) {
  3. return x + y;
  4. } else {
  5. return x;
  6. }
  7. }
  8. myFn(1) //1

参数默认值

在es6中,我们允许给参数添加默认值,在ts中依然可以. 此时就不受在可选参数必须在必选参数后面的限制了。

  1. let myFn = function (x: number, y?: number, z: string = '3', d: number = 5): number {
  2. if(y) {
  3. return x + Number(z) + d;//1 + 4 + 5
  4. } else {
  5. return Number(z) + x;
  6. }
  7. }
  8. myFn(1,2,'4') //10

剩余参数

es6中可以使用…rest来表示剩余参数。下面看一个简单的示例,我们可以看到items是一个数组。

  1. function Fn(a, ...items) {
  2. console.log(items);//[2,3,4]
  3. }
  4. Fn(1,2,3,4);

所在,我们在ts中就可以使用数组的形式定义它。

  1. function F(a: number, ...items: any[]) {
  2. items.push(a)
  3. }
  4. F(1,2,3,4);

函数重载

重载允许一个函数接受不同数量数量或者类型时,作出不同的处理。有这样一个案例:输入123时输出321,输入abc时,输出cba。这时候我们很容易想到联合类型。

  1. function reverse(x: number | string): number | string {
  2. if (typeof x === 'number') {
  3. return Number(x.toString().split('').reverse().join(''));
  4. } else if (typeof x === 'string') {
  5. return x.split('').reverse().join('');
  6. }
  7. }

如果使用函数重载的方式,我们可以这样去写,前面两次是函数的定义,最后一次是函数的实现,优先会从前面开始匹配。

  1. function reverse(x: number): number;
  2. function reverse(x: string): string;
  3. function reverse(x: number | string): number | string {
  4. if (typeof x === 'number') {
  5. return Number(x.toString().split('').reverse().join(''));
  6. } else if (typeof x === 'string') {
  7. return x.split('').reverse().join('');
  8. }
  9. }