【TypeScript】对函数类型的约束定义

导读

函数是JavaScript 中的 一等公民
概念:函数类型的概念是指给函数添加类型注解,本质上就是给函数的参数和返回值添加类型约束

文章目录

  • 声明式函数:
  • 表达式函数:
  • 箭头函数
    • 可选参数和默认参数:
    • 参数默认值:
    • 过剩参数的处理:
    • 函数重载:
    • 函数的 Void 类型
    • 函数的 never 类型
  • 总结:

【TypeScript】对函数类型的约束定义_第1张图片

声明式函数:

在 TypeScript 中,一个函数有输入和输出,需要对其进行约束,需要把输入和输出都考虑到。

其中函数声明式的类型定义较简单:

可以给要接收的参数指定类型,也可以给函数的返回值约束类型。

//函数表达式,命名函数
function add(a: number, b: number): number {
    return a + b
}

上述案例说明:

  • 当函数参数被注解类型之后,不但约束了传递参数的类型,还限制了参数为必填
  • 函数返回值被类型注解后,也限制了函数体内部 return 出去的值,必须要满足类型要求

函数添加类型注释的好处是:

  • 避免以为参数不对,导致的函数内部逻辑错误
  • 对函数起到说明作用

注意:
输入多余的(或者少于要求的)参数,是不被允许的

//函数表达式,命名函数
function add(a: number, b: number): number {
    return a + b
}
console.log(add(5, 2 , 1));

【TypeScript】对函数类型的约束定义_第2张图片

表达式函数:

如果要我们现在写一个对函数表达式的定义,可能会写成这样:

//函数表达式,匿名函数
let sum = function (a: number, b: number): number {
    return a + b
}

箭头函数

//函数表达式,回调箭头函数
let callback = (a: number, b: number): number => {
    return a + b
}

箭头函数 表达式 还可以使用 【类型别名】 来进一步简化函数类型注解

注意:类型别名 抽离类型的方式,只能运用在 箭头函数表达式中

type ADD = (a: number, b: number) => number //通过类型别名,对类型进行抽离,还可达到复用的效果。

let callback: ADD = (a, b) => {
    return a + b
}

let n = callback(12, 96)
console.log(n);  //108

这样也是可以通过编译的,不过事实上,上面的代码只对等号右侧的匿名函数进行了类型定义,而等号左边的 callback 和 sum,是通过赋值操作进行类型推论而推断出来的,严格意义上来说,在TS中,这并不是最完整的写法。所以完整的写法需要我们手动给 函数 添加类型,则应该是这样:

匿名函数完整版写法:

//函数表达式,命名函数
let sum: (a: number, b: number) => number = function (a: number, b: number): number {
    return a + b
}

箭头函数表达式完整版写法:

//函数表达式,回调箭头函数
let callback: (a: number, b: number) => number = (a: number, b: number): number => {
    return a + b
}

注意
千万不要混淆了 TypeScript 中的=>和 ES6 中的 =>在 TypeScript 的类型定义中,=>用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型


可选参数和默认参数:

可选参数:

前面提到的方式,如果输入多余的(或者少于要求的)参数,是不被允许的。但有时候,传递的参数是处于未知的,这时候就需要配置 可选参数了

Infinity 接口定义类型中的可选属性类似,我们用 ? 表示可选的参数

//声明式函数
function add(a: number, b?: number): number {
    return a + b
}
//函数表达式,命名函数
let sum: (a: number, b?: number) => number = function (a: number, b: number): number {
    return a + b
}
//函数表达式,回调箭头函数
let callback: (a: number, b?: number) => number = (a: number, b: number): number => {
    return a + b
}

// 这时候当我们只一个参数值的时候,也不会报错!!!
console.log(add(5));
console.log(sum(3));
console.log(callback(9));

注意:

定义可选参数后,可选参数必须接在必需参数后面。换句话说,可选参数后面不允许再出现必需参数了,可选参数可以不传,但是一但传了,也依然需要约束其类型。

【TypeScript】对函数类型的约束定义_第3张图片

参数默认值:

ES6 中,我们允许给函数的参数添加默认值,TypeScript 中会将添加了默认值的参数自动识别为可选参数

值得注意: 除声明式函数可以直接赋值默认值外,函数表达式,以及回调函数表达式,定义默认值,必须要搭配 ?可选属性。

//函数声明 ,命名函数
function add(a: number, b: number = 123): number {
    return a + b
}
//函数表达式,命名函数
let sum: (a: number, b?: number) => number = function (a: number, b: number = 798): number {
    return a + b
}
//函数表达式,回调箭头函数
let callback: (a: number, b?: number) => number = (a: number, b: number = 456): number => {
    return a + b
}

console.log(add(5));
console.log(sum(3));
console.log(callback(9));

此时就不受「可选参数必须接在必需参数后面」的限制了


过剩参数的处理:

在ES6 中,可以使用 ...来整合或解构参数,在TypeScript 中同样可以使用 ... 的方式获取函数中的剩余参数(rest 参数)

//函数声明 ,命名函数
function add(a?: number, b: number = 132, ...args: number[]): number {
    console.log(args); //[7, 9, 6]
    return a + b
}
//函数表达式,命名函数
let sum: (a: number, b?: number, ...args: number[]) => number = function (a: number, b: number = 798, ...args: number[]): number {
    console.log(args); // [4, 7, 9, 6]
    return a + b
}
//函数表达式,回调箭头函数
let callback: (a: number, b?: number, ...args: number[]) => number = (a: number, b: number = 456, ...args: number[]): number => {
    console.log(args); //[5, 4, 7, 9, 6]
    return a + b
}

console.log(add(5, 4, 7, 9, 6));
console.log(sum(3, 5, 4, 7, 9, 6));
console.log(callback(9, 3, 5, 4, 7, 9, 6));

事实上,args 是一个数组。所以我们可以用数组的类型来定义它:

注意... 整合参数只能是最后一个参数。


函数重载:

定义了一个 add 函数,希望可以对字符串和数字类型进行相加:

function add(a1: number | string, a2: number | string) {
    return a1 + a2; // 报错
  }
  
  // 方式一:联合类型
  function add(a1: number | string, a2: number | string) {
    if (typeof a1 === "number" && typeof a2 === "number") {
      return a1 + a2;
    } else if (typeof a1 === "string" && typeof a2 === "string") {
      return a1 + a2;
    }
  }
  
//   add(10, 20);
  /**
   * 通过联合类型有两个缺点:
   *  1.进行很多的逻辑判断(类型缩小)
   *  2.返回值的类型依然是不能确定
   *  3.返回值不能够精确的表达,输入为数字的时候,输出也应该为数字,输入为字符串的时候,输出也应该为字符串。
   */
  
  // 解决方式二:函数重载 函数的名称相同, 但是形参不同的多个函数, 就是函数的重载
  // 我们可以去编写不同的重载签名(overload signatures)来表示函数可以以不同的方式进行调用
  // 一般是编写两个或者以上的重载签名,再去编写一个通用的函数实现
  function add(num1: number, num2: number): number; // 没函数体
  function add(num1: string, num2: string): string;
  
  // 具体实现函数,不能直接调用来处理逻辑哦
  function add(num1: any, num2: any): any {
    if (typeof num1 === "string" && typeof num2 === "string") {
      return num1.length + num2.length;
    }
    return num1 + num2;
  }
  
  const result1 = add(20, 30);
  const result2 = add("abc", "cba");
  console.log(result1);
  console.log(result2);

函数的 Void 类型

Void 类型 表示无返回值
概念:JS中的有些函数只有功能没有返回值,此时使用void进行返回值注解,明确表示函数没有函数值

注意事项: :在JS中如何没有返回值,默认返回的是undefined,在TS中 void和undefined不是一回事,undefined在TS中是一种明确的简单类型,如果指定返回值为undefined,那返回值必须是undefined类型

void 返回值类型,约束了,函数不能返回 “有效值” ,可以返回 null,undefined,或者 只有 return 关键字,更甚至,return 关键字都可以不需要存在。就是不能返回 任何 有效值

function fn(): void {
    // return null
    // return undefined
    return
}

函数的 never 类型

与 Void 类型类似,不过比 Void 类型,更加的绝对化,函数体中,连 return 关键字都不能出现,一但出现 return 关键字,不论有没有返回有效值,就会报错。所以说从某种意义上来说。never 类型 是 void 类型的 升级严格模式版

function fn():never{
    throw new Error('终止')
}

总结:

本章节,主要给大家介绍了,在 TypeScript 中,围绕着函数,来对函数做一系列的,类型约束的使用讲解。毫无疑问,函数在 JS 或 TS 中,都扮演十分重要的角色,所以掌握它,也是必备的技能之一。


‍♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
‍♂️ 如果都看到这了,博主希望留下你的足迹!【收藏!点赞!✍️评论!】
——————————————————————————————

你可能感兴趣的:(TypeScript,typescript,javascript,前端)