TS中的函数类型

163 阅读3分钟

函数返回值

TS 定义函数类型需要定义输入参数类型和输出类型。

输出类型也可以忽略,因为 TS 能够根据返回语句自动推断出返回值类型。

function add(x:number, y:number):number {
    return x + y
}
let num:number = add(1,2)
console.log(num) //3

函数没有明确返回值,默认返回 Void 类型

function welcome(): void {
    console.log('hello');
}

函数表达式写法

let add2 = (x: number, y: number): number => {
    return x + y
}

可选参数

参数后加个问号,代表这个参数是可选的

function add(x:number, y:number, z?:number):number {
    return x + y
}

add(1,2,3)
add(1,2)

==注意可选参数要放在函数入参的最后面,不然会导致编译错误。==

默认参数

跟 JS 的写法一样,在入参里定义初始值

function add(x:number, y:number = 100):number {
    return x + y
}

add(100)  // 200

和可选参数不同的是,默认参数可以不放在函数入参的最后面,==但是要注意传参==

function add(x:number = 100, y:number):number {
    return x + y
}

add(100) 

看上面的代码,add 函数只传了一个参数,如果理所当然地觉得 x 有默认值,只传一个就传的是 y 的话,就会报错, 编译器会判定你只传了 x,没传 y。 如果带默认值的参数不是最后一个参数,用户必须明确的传入 undefined值来获得默认值。

add(undefined,100) // 200

函数赋值

JS 中变量随便赋值没问题 但在 TS 中函数不能随便赋值,会报错的。

也可以用下面这种方式定义一个函数 add3,把 add2 赋值给 add3

let add2 = (x: number, y: number): number => {
    return x + y
}

const add3:(x: number, y: number) => number = add2

有点像 es6 中的箭头函数,但不是箭头函数,TS 遇到 : 就知道后面的代码是写类型用的 当然,不用定义 add3 类型直接赋值也可以,TS 会在变量赋值的过程中,自动推断类型.

函数重载

函数重载是指两个函数名称相同,但是参数个数或参数类型不同,他的好处显而易见,不需要把相似功能的函数拆分成多个函数名称不同的函数。

不同参数类型

比如我们实现一个 add 函数,如果传入参数都是数字,就返回数字相加,如果传入参数都是字符串,就返回字符串拼接,

function add(x: number[]): number
function add(x: string[]): string
function add(x: any[]): any {
  if (typeof x[0] === 'string') {
    return x.join()
  }
  if (typeof x[0] === 'number') {
      return x.reduce((acc, cur) => acc + cur)
  }
}

在 TS 中,实现函数重载,需要多次声明这个函数,前几次是函数定义,列出所有的情况,最后一次是函数实现,需要比较宽泛的类型,比如上面的例子就用到了 any

不同参数个数

假设这个 add 函数接受更多的参数个数,比如还可以传入一个参数 y,如果传了y,就把 y 也加上或拼接上,就可以这么写,

function add(x: number[]): number
function add(x: string[]): string
function add(x: number[], y: number[]): number
function add(x: string[], y: string[]): string
function add(x: any[], y?: any[]): any {
  if (Array.isArray(y) && typeof y[0] === 'number') {
      return x.reduce((acc, cur) => acc + cur) + y.reduce((acc, cur) => acc + cur)
  }
  if (Array.isArray(y) && typeof y[0] === 'string') {
      return x.join() + ',' + y.join()
  }
  if (typeof x[0] === 'string') {
    return x.join()
  }
  if (typeof x[0] === 'number') {
      return x.reduce((acc, cur) => acc + cur)
  }
}


console.log(add([1,2,3]))      // 6
console.log(add(['lin', '18']))  // 'lin,18'
console.log(add([1,2,3], [1,2,3])) // 12
console.log(add(['lin', '18'], ['man', 'handsome'])) // 'lin,18,man,handsome'

其实写起来挺麻烦的,后面了解泛型之后写起来会简洁一些,不必太纠结函数重载,知道有这个概念即可,平时一般用泛型来解决类似问题。