Skip to content
目录

基础篇-函数

声明方式

  • 通过 function
  • 通过变量
  • 通过接口
  • 通过类型别名
ts
// 函数定义
function add1(x: number, y: number) {
  return x + y;
}

// 通过变量
let add2: (x: number, y: number) => number;

// 通过类型别名
let add3 = (x: number, y: number) => number;

// 通过类型别名
interface add4 {
  (x: number, y: number): number;
}

函数声明方式创建函数,括号中规定了函数参数的类型;最后一个冒号后面规定函数返回值类型

js
function sum(x: number, y: number): number {
  return x + y;
}

表达式方式创建函数,参数类型和返回值类型的规定与上面是一样的

js
let mySum = function (x: number, y: number): number {
  return x + y;
};

上面的代码只对等号右侧的匿名函数进行了类型定义,而等号左边的 mySum,是通过赋值操作进行类型推论而推断出来的。如果需要我们手动给 mySum 添加类型,则应该是这样:

js
let mySum: (x: number, y: number) => number = function (
  x: number,
  y: number,
): number {
  return x + y;
};

输入多余的(或者少于要求的)参数,是不被允许的

js
function sum(x: number, y: number): number {
  return x + y;
}
sum(1, 2, 3);
//报错
js
function sum(x: number, y: number): number {
  return x + y;
}
sum(1);
//报错

可选参数

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

js
const addR = (x: number, y: number, z?: number): number => {
  return x + y;
};
console.log(addR(1, 2));

经过修改,参数 z 变为可选参数,检查通过。

默认参数

与 JavaScript 相同,在 TypeScript 里函数参数同样可以设置默认值,用法一致。

js
function add(x: number, y = 2): number {
  return x + y;
}

根据类型推断机制,参数 y 为推断为 number 类型

ES6 中函数参数的默认值

剩余参数

与 JavaScript 相同。TypeScript 可以把所有参数收集到一个变量里。

WARNING

剩余参数必须在必选参数之后,可选参数不允许和剩余参数共同出现在一个函数内。

js
function add(x: number, ...rest: number[]) {
  return x + rest.reduce((prev, curr) => prev + curr);
}

add(1, 2, 3); // 6

函数重载

重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。

比如,我们需要实现一个函数 reverse,

  • 输入数字 123 的时候,输出反转的数字 321,
  • 输入字符串 'hello' 的时候,输出反转的字符串 'olleh'。

利用联合类型,我们可以这么实现:

js
function reverse(x: number | string): number | string | undefined {
  if (typeof x === 'number') {
    return Number(x.toString().split('').reverse().join(''));
  } else if (typeof x === 'string') {
    return x.split('').reverse().join('');
  }
}

然而这样有一个缺点,就是不能够精确的表达,输入为数字的时候,输出也应该为数字,输入为字符串的时候,输出也应该为字符串。 这时,我们可以使用重载定义多个 reverse 的函数类型:

js
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | undefined {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

上例中,我们重复定义了多次函数 reverse,前几次都是函数定义,最后一次是函数实现。在编辑器的代码提示中,可以正确的看到前两个提示。 注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。

js
function getUserInfo(name: string): string;
function getUserInfo(name: string, age: number): string;
function getUserInfo(name: string, age?: number): string | number {
    if (age) {
        return `我叫${name},年龄${age}岁了`;
    } else {
        return `我叫${name}`;
    }
}

console.log(getUserInfo('黎明')); //正确
console.log(getUserInfo(123)); //错误
console.log(getUserInfo('黎明', 123)); //正确