Skip to content

函数类型

基本函数类型写法

ts
// 方式 1:类型别名
type Add = (a: number, b: number) => number

// 方式 2:接口
interface AddFn {
  (a: number, b: number): number
}

const add: Add = (a, b) => a + b

两者等价,区别在于:

  • type 可以用联合、交叉
  • interface 可以合并、继承

可选参数

ts
type Greet = (name: string, age?: number) => string

const greet: Greet = (n, a) => a ? `${n} - ${a}` : n
  • age?: number 表示参数可以不传

  • 可选参数必须放在必选参数之后

默认参数

ts
function multiply(a: number, b: number = 2): number {
  return a * b
}

警告

可选参数和默认参数不能同时出现

返回值

ts
function log(msg: string): void {
  console.log(msg)
}

function fail(msg: string): never {
  throw new Error(msg)
}

void:无返回值(或返回 undefined

never:永远不会返回(死循环、抛异常)

函数重载

JS实际上没有函数重载,TS中的函数重载实际上是声明多个相同名字的函数声明,实际实现的函数只有一个。因此实现函数需要做到兼容多个重载签名。

函数重载的意义实际上是在编码层面上明确的告诉使用者该函数有多少种使用方法

ts
// 重载签名
function getElement(selector: string): HTMLElement | null
function getElement(selector: string, all: true): NodeListOf<HTMLElement>

// 实现签名
function getElement(selector: string, all?: boolean) {
  if (all) {
    return document.querySelectorAll<HTMLElement>(selector)
  }
  return document.querySelector<HTMLElement>(selector)
}

// 使用
const single = getElement('#app')     // HTMLElement | null
const all = getElement('.item', true) // NodeListOf<HTMLElement>

定义this的类型

可以显式声明 this 的类型,this必须定义在函数的一个形参:

ts
interface Person {
  name: string
  greet(this: Person): void
}

const p: Person = {
  name: "Alice",
  greet() {
    console.log(`Hello, I'm ${this.name}`)
  }
}

信息

his: Person 只在 TS 类型层面有效,编译后不会生成参数。