函数类型与重载
写给初学者:每个概念都从”为什么需要它”开始讲,配合通俗比喻和完整可运行代码。
为什么需要函数类型?
在 TypeScript 里,函数是”一等公民”——和数字、字符串一样,可以当变量存、当参数传、当返回值返回。这时候就需要描述”这个函数长什么样”。
函数声明与类型标注
// 方式 1:函数声明
function add(a: number, b: number): number {
return a + b;
}
// 方式 2:箭头函数
const multiply = (a: number, b: number): number => a * b;
// 方式 3:函数类型标注
type MathFunc = (a: number, b: number) => number;
const divide: MathFunc = (a, b) => a / b;可选参数和默认参数
// 可选参数(? 标记,必须放在必填参数后面)
function greet(name: string, greeting?: string): string {
return `${greeting || "你好"}, ${name}!`;
}
// 默认参数(比可选参数更简洁)
function greet2(name: string, greeting: string = "你好"): string {
return `${greeting}, ${name}!`;
}
greet2("张三"); // "你好, 张三!"
greet2("张三", "早上好"); // "早上好, 张三!"剩余参数(rest parameters)
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
sum(1, 2, 3); // 6
sum(10, 20, 30, 40); // 100
sum(); // 0
// 搭配其他参数
function log(level: string, ...messages: string[]) {
console.log(`[${level}]`, ...messages);
}
log("INFO", "用户登录", "IP: 127.0.0.1");函数重载(Overloads)
有些函数根据参数类型不同,返回值类型也不同:
// 没有重载的问题
function double(value: string | number): string | number {
if (typeof value === "string") return value + value;
return value * 2;
}
const r1 = double("ha"); // r1 的类型是 string | number(不确定!)
// 用函数重载解决
function double2(value: string): string; // 传 string 返回 string
function double2(value: number): number; // 传 number 返回 number
function double2(value: string | number): string | number {
if (typeof value === "string") return value + value;
return value * 2;
}
const r2 = double2("ha"); // r2 的类型是 string(精确!)
r2.toUpperCase(); // ✅
const r3 = double2(21); // r3 的类型是 number
r3.toFixed(2); // ✅通俗比喻:函数重载就像自动贩卖机——你投硬币(参数),机器根据你投的是纸币还是硬币(参数类型),给你不同面额的找零(返回值类型)。机器(实现)只有一台,但投币口(重载签名)有好几种。
回调函数类型
type Callback = (data: string, error?: string) => void;
function fetchData(url: string, callback: Callback) {
if (url.includes("error")) {
callback("", "请求失败");
} else {
callback('{"name": "张三"}');
}
}
fetchData("https://api.example.com/user", (data, error) => {
if (error) {
console.log("出错了:", error);
} else {
console.log("拿到数据:", data);
}
});
// 事件处理函数类型
type EventHandler = (event: { type: string; target: unknown }) => void;
const handleClick: EventHandler = (event) => {
console.log("点击了:", event.type);
};速查表
| 概念 | 一句话解释 | 关键代码 |
|---|---|---|
| 可选参数 | 函数参数可以不传 | function f(name: string, age?: number) |
| 默认参数 | 参数有默认值 | function f(name: string, g = "你好") |
| 剩余参数 | 收集多余参数为数组 | function f(...args: number[]) |
| 函数重载 | 同一函数根据参数类型返回不同类型 | 多个签名 + 一个实现 |
void | 函数没有返回值 | function f(): void |
速记卡(面试闪卡)
Q1:一句话讲清「函数类型与重载」到底是什么? A:TS 里函数是头等公民需描述其”长相”:用类型标注声明签名,重载用多个签名+一个实现,让不同参数类型返回精确类型而非联合类型。
Q2:函数类型与声明方式 —— 怎么理解? A:TS 里函数和数、字符串一样能存能传能返回,于是要描述”这个函数长什么样”。三种写法:函数声明 function、箭头 const f = ()=>、类型标注 type F = (a,b)=>c。类型标注让变量只能装符合同签名的函数。
Q3:可选 / 默认 / 剩余参数 —— 怎么理解? A:可选参数用 ? 且必须放必填后;默认参数更简洁,不传就用默认值;剩余参数 …nums 把多余参数收成数组,还能搭配其他参数。三者解决”参数个数不固定”的问题,是灵活函数签名的基础。
Q4:函数重载 Overloads —— 怎么理解? A:没重载时,double(‘ha’) 返回类型被推成 string|number,后续 .toUpperCase 报错。重载写多个签名(传 string 返 string、传 number 返 number)+ 一个实现,调用处就能拿到精确类型。像自动贩卖机:投币口几种,机器只有一台。
Q5:回调函数类型 —— 怎么理解? A:事件处理、异步回调都要给函数”画像”:type Callback = (data, error?)=>void。fetchData 收 url 和回调,成功带 data、失败带 error,调用方在回调里分流。事件处理函数同理用 (event)=>void 约束,保证传进来的函数形状正确。
Q6:核心速记主线有哪些?
- 函数类型:头等公民需类型标注描述签名
- 可选 ? / 默认 / 剩余 … 三类参数
- 重载:多签名 + 一实现,返回精确类型
- 比喻:自动贩卖机,多投币口一台机器
- 回调类型:用 type 约束 (data, error?) => void
口诀 A:TS 函数是公民,类型标注画其形; 可选默认剩余参,个数不固定也行; 重载多签一实现,返回精确不联名; 回调画像 type 定,投币贩卖机口清。
相关链接
- 目录:00-TypeScript
- 上一篇:03-泛型generics
- 下一篇:JSX与组件