# 函数

与JavaScript一样,函数同样是Typescript应用程序的基础,是定义行为的地方。

# 举个🌰

两种方式定义函数:匿名函数 & 命名函数

  let myfn = function () {
    console.log('匿名函数')
  }
  myfn()
  //
  function myfn1() {
    console.log('命名函数')
  }
  myfn1()

# 函数类型

每个参数添加类型之后,可以给函数本身添加返回值类型。

  let add = function (a: number, b: number): number {
    return a + b
  }
  console.log(add(1, 2))
  function add1(a: number, b: number): string {
    return a + b // 报错:不能将类型“number”分配给类型“string”。
  }
  console.log(add1(4, 5))

# 参数

Typescript函数中,传递给函数的参数个数必须与函数期望的参数个数保持一致。

编译器会检查每个参数都传入了值(包括undefined & null)。编译器还会假设只有这些参数会被传递进函数。

# 默认参数

TypeScript可以为参数提供一个默认值,当没有传递这个参数或传递的值是undefined时,🉑️默认初始化该参数的值

改造下🌰

  function add1(a: number = 0, b: number): number {
    return a + b
  }
  console.log(add1(undefined, 5)) // 5

# 可选参数

与Javascript不同,JavaScript中每个参数都是可选的,🉑️传🉑️不传,没有传参时,该参数的默认值为undefined

Typescript中在参数名旁边使用?实现可选功能,

❗️ 可选参数必须置于必选参数后面,意味着可选参数不能是第一个参数

改造下🌰

  function add1(a: number, b?: number): number {
    if (b) {
      return a + b
    } else {
      return a
    }
  }
  console.log(add1(4, 5))

# 剩余参数

以上默认参数/必选参数/可选参数都对应某一个参数,当不确定有多个参数传递时,Javascript可以用arguments

Typescript可以使用...,把所有参数存放到一个数组中,类似ES6的写法。

这些剩余参数会被当作不限量的可选参数,可以多个/一个/甚至零个

  function args(n: number, ...nums:number[]) {
    console.log(n, nums)
  }
  args(1, 2, 3, 4, 5) // 1 [2, 3, 4, 5]

# 函数重载

函数名相同,而形参不同的多个函数

在Javascript中,因为弱类型的特点以及形参和实参可以不匹配,所以没有函数重载

但在Typescript与其他面向对象的语言中(Java等)就有函数重载

  function add(x: string | number, y: string | number): string | number {
    return x + y
  }
  console.log(add(1, 2)) 
  //报错 Operator '+' cannot be applied to types 'string | number' and 'string | number'

上面🌰参数和返回值支持联合类型,不能直接使用+操作符,改造下

  function add(x: string | number, y: string | number): string | number {
    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)) // 3
  console.log(add('勒布朗', '詹姆斯')) // 勒布朗詹姆斯
  console.log(add(1, '詹姆斯')) // undefined
  console.log(add('勒布朗', 2)) // undefined

重载函数声明

  //  重载函数声明必须放在函数实现前,不然报错:函数实现缺失或未立即出现在声明之后
  function add(x: string, y: string): string
  function add(x: number, y: number): number
  // 定义函数实现
  function add(x: string | number, y: string | number): string | number {
    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)) // 3
  console.log(add('勒布朗', '詹姆斯')) // 勒布朗詹姆斯
  // console.log(add(1, '詹姆斯')) // 报错:没有与此调用匹配的重载。
  // console.log(add('勒布朗', 2)) // 报错:没有与此调用匹配的重载。