函数类型
参数与返回值、可选参数、箭头函数 typing。
函数类型
这一课你将能做到
- 给函数声明、函数表达式、箭头函数标注完整的参数和返回值类型
- 正确使用可选参数、默认参数、剩余参数,并理解它们在类型层面的表现
- 用函数类型签名和重载描述「同一个函数多种调用方式」的场景
为什么要学
函数是 JavaScript 的一等公民,也是 TS 类型注解出现频率最高的地方。你写的每一个回调、map/filter 的入参、React 的事件处理函数,背后都是函数类型。
函数类型标注有个核心思想:函数的类型 = 输入(参数)+ 输出(返回值)。把这两个写准,TS 就能帮你检查所有调用点。函数参数是类型推断唯一「推不出来」的地方——所以函数参数必须手写注解,这是 TS 世界的一条铁律。
先建立图像
一个完整函数类型的解剖:
参数名 参数类型 返回值类型
│ │ │
function add(a: number, b: number): number {
return a + b;
}
│
函数名
整个函数的类型签名:(a: number, b: number) => number
参数列表 返回值
注意类型签名里的箭头 => 和箭头函数的 => 长得像但含义不同:前者出现在类型位置,表示「返回」;后者出现在值位置,是函数定义语法。
跟着做
新建 functions-demo.ts,每步代码可直接 tsc 编译运行。
步骤 1:函数声明与函数表达式的标注
// 函数声明:参数和返回值都标在函数头上
function multiply(a: number, b: number): number {
return a * b;
}
// 函数表达式:两种方式
// 方式 A:只标函数本身(推荐,简洁)
const divide = function (a: number, b: number): number {
return a / b;
};
// 方式 B:给变量标注完整函数类型(赋值给配置、接口时常用)
const subtract: (a: number, b: number) => number = function (a, b) {
return a - b; // 参数类型从签名推断,不用重复写
};
console.log(multiply(3, 4), divide(10, 2), subtract(10, 3));
// 12 5 7
步骤 2:箭头函数与返回值推断
// 显式标注返回值
const square = (n: number): number => n * n;
// 返回值可推断时省略(推荐)
const double = (n: number) => n * 2; // TS 推断返回 number
// 无返回值
const log = (msg: string): void => {
console.log(msg);
};
const nums = [1, 2, 3].map(double); // 回调参数 n 自动推断为 number
console.log(nums, square(5)); // [ 2, 4, 6 ] 25
经验:返回值类型大多数时候让 TS 推断;只有两种情况下手写——函数体复杂想给读者看契约、或要强制返回值符合某类型(写错能当场报错)。
步骤 3:可选参数与默认参数
// 可选参数:参数名后加 ?
function greet(name: string, greeting?: string): string {
return `${greeting ?? "你好"},${name}`;
}
console.log(greet("小明")); // 你好,小明
console.log(greet("小明", "早上好")); // 早上好,小明
// 默认参数:直接写默认值,类型自动推断,调用时可省略
function createUser(name: string, role: string = "viewer"): string {
return `${name}(${role})`;
}
console.log(createUser("小红")); // 小红(viewer)
console.log(createUser("管理员", "admin")); // 管理员(admin)