前言

本文主要记录下 TypeScript 中的函数,日常学习总结篇。 

在 JavaScript 中,函数是构建应用的一块基石,我们可以使用函数抽离可复用的逻辑、抽象模型、封装过程。在 TypeScript 中,函数仍然是最基本、最重要的概念之一。

一、函数类型定义

1⃣️、直接定义函数类型

函数类型包括两部分:参数类型和返回值类型。

// 函数声明 命名函数
function add(x: number, y: number): number {
  return x + y
}

// 函数表达式 匿名函数
const add = (x: number, y: number): number => {
  return x + y
}

定义函数时,如果省略参数的类型,TypeScript 会默认这个参数为 any 类型;如果省略返回值类型,函数无返回值时,TypeScript 会默认函数返回值为 viod 类型;函数有返回值时,TypeScript 会根据定义的逻辑推断出返回类型。

// 完整的函数类型
const add: (x: number, y: number) => number = (x: number, y: number): number => x + y

// 省略左侧
const add = (x: number, y: number): number => x + y

// 省略右侧
const add: (x: number, y: number) => number = (x, y) => x + y

2⃣️、接口定义函数类型

interface Add {
  (x: number, y: number): number
}

const add: Add = (x: number, y: number): number => x + y

3⃣️、类型别名定义函数类型

type Add = (x: number, y: number) => number

const add: Add = (x: number, y: number): number => x + y

注意:这里的 => 与 ES6 中箭头函数的 => 不同。TypeScript 函数类型中的 => 用来表示函数的定义,其左侧是函数的参数类型,右侧是函数的返回值类型;而 ES6 中的 => 是函数的实现。

二、函数参数定义

1⃣️、可选参数

在 TypeScript 中函数的形参和实参类型数量必须保持一致,但有时,函数有些参数不是必须的,这时可以将函数的参数设置为可选参数。可选参数只需在参数名后加一个 ? 即可。

注意:可选参数必须放在必选参数后面。

type FullName = (firstName: string, lastName?: string) => string

const getFullName: FullName = (firstName: string, lastName?: string): string => {
  return lastName ? `${firstName}-${lastName}` : firstName
}

2⃣️、默认参数

当用户没有给一个参数传值或者传的值是 undefined 时,这个参数叫做可以有默认值的参数。默认参数是参数后面跟 = 号,之后跟默认值。

const getFullName = (firstName: string, lastName: string = "Jenny"): string => {
  return `${firstName}-${lastName}`
}

注意:在所有必选参数后面带默认值的参数都是可选的, 与可选参数一样,在调用函数的时候可以省略;与普通可选参数不同的是,带默认值的参数不需要放在必须参数的后面,如果带默认值的参数出现在必选参数前面,必须明确的传入 undefined 值来获得默认值。

3⃣️、剩余参数

必选参数、默认参数和可选参数有个共同点:它们表示某一个参数。但有时,我们想同时操作多个参数,或者你并不知道会有多少参数传递过来,这时便用到剩余参数。

const getMaxNum = (a: number, b: number, ...arr: number[]): number => {
  return Math.max(a, b, ...arr)
}

console.log(getMaxNum(2, 1, 7, 3, 9, 0)) // 9

剩余参数会被当做个数不限的可选参数。可以一个都没有,同样也可以有任意个。 

三、函数重载

TypeScript 的函数重载通过为一个函数提供多个函数类型定义,从而对函数调用的返回值进行检查。

// 重载函数声明
function add(x: string, y: string): string
function add(x: number, y: number): number

// 定义函数实现
function add(x: string | number, y: string | number): string | number {
  // 在实现上我们要注意严格判断两个参数的类型是否相等,而不能简单的写一个 x + y
  if (typeof x === 'string' && typeof y === 'string') {
    return x + y
  } else if (typeof x === 'number' && typeof y === 'number') {
    return x + y
  }
}

console.log(add(1, 2))
console.log(add('a', 'b'))
// console.log(add(1, 'a')) // error

注意:函数重载只能用 function 来定义,不能使用接口、类型别名来定义。