Skip to content

函数类型

简介

在 TypeScript 中,函数的声明可以定义函数的参数和返回值的类型。

函数类型的定义有很多写法,先来看最常规的写法:

typescript
function add(x: number, y: number): number {
  return x + y;
}

如上所示,函数 add 接受两个参数 xy,它们的类型都是 number,并且返回值的类型定义为 number

这种写法返回值的类型可以省略,TypeScript 会根据函数的实现自动推断出返回值的类型。因此,上面的函数可以简化为:

typescript
function add(x: number, y: number) {
  return x + y;
}

因为参数 xy 的类型都是 number,所以 TypeScript 可以推断出返回值的类型也是 number

假如函数没有返回值,这时返回值的类型将被 TypeScript 自动推断为 void(表示什么都不返回):

typescript
function print(message: string) { 
  console.log(message);
}
// 实际类型为 (message: string) => void

第二种写法,语法比较严格一点,要求在函数体之前声明好函数的参数类型以及返回值类型:

ts
const add: 
  (x: number, y: number) => number 
= function (x, y) {
  return x + y
};

返回值的类型必须写,即使该函数什么也不返回,此时返回值的类型需显式写成 void;

WARNING

第二种写法的 "=>" 符号并代表箭头函数,两者只是语法类似。

第三种写法不太常见,采用对象的写法:

ts
let add:{
  (x:number, y:number):number
};
 
add = function (x, y) {
  return x + y;
};

第四种写法,利用 interface 进行声明,详见 接口 章节。

ts
interface IAdd {
  (a:number, b:number): number;
}

const add: IAdd = (a, b) => a + b;
箭头函数

箭头函数是 ES6 新增的语法,它的写法更加简洁,在 TypeScript 中,一般不需要特别定义箭头函数,它的写法与普通函数类似。

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

可选参数

在 JavaScript 中,函数的参数是可选的,即可以不传参数。在 TypeScript 中,可以通过在参数名后面加上 ? 来定义可选参数:

ts
function buildName(firstName: string, lastName?: string) {
  if (lastName) {
    return firstName + ' ' + lastName;
  } else {
    return firstName;
  }
}

在上面的例子中,lastName 参数是可选的,实际上它的类型是 string | undefined

默认参数

在 JavaScript 中,函数的参数可以有默认值,即在调用函数时,如果不传参数,则会使用默认值。在 TypeScript 中,可以通过在参数后面直接赋值来定义默认参数:

ts
function buildName(firstName: string, lastName = 'Smith') {
  return firstName + ' ' + lastName;
}

由于lastName的默认值为Smith,所以lastName的类型会为推断为string,当然,显式地为lastName指定类型也是没有问题的:

ts
function buildName(firstName: string, lastName: string = 'Smith') {
  return firstName + ' ' + lastName;
}

参数解构

函数参数解构的语法如下:

ts
function print({name, age}: {name: string, age: number}) {
  console.log(name, age);
}

数组解构的语法是类似的,参照es6的解构赋值语法即可。

剩余参数

剩余参数,即rest参数,用于获取函数的剩余参数,可以使用 ... 来定义,根据剩余参数类型可表示为数组或元组:

ts
function sum(...args: number[]) {
  return args.reduce((prev, curr) => prev + curr, 0);
}

function print(...args: [string, number]) {
  console.log(args[0], args[1]);
}

函数重载

函数重载是指允许一个函数接受不同数量或类型的参数时,作出不同的处理。在 TypeScript 中,同样支持函数重载:

ts
function reverse(x: number): number;
function reverse(x: string): string;

构造函数

构造函数是指类的实例化过程,它的类型可以通过 new 关键字来定义:

ts
class Person {
  age:number = 8;
}

type PersonConstructor = new () => Person;

function create(c:personConstructor):Person {
  return new c();
}

const p = create(person);

或者用对象形式定义:

ts
type SomeConstructor = {
  new (s: string): SomeObject;
};

某些函数既是构造函数,又可以当作普通函数使用,比如Date()。这时,类型声明可以写成下面这样:

ts
interface CallOrConstruct {
  (n?: number): string;
  new (s: string): Date;
}