TypeScript 如何做回调类型
写代码时,我们常常需要把一段“要做的事”打包传给别人,等对方准备好后再执行——这种“延后执行的函数”就是回调。但如果回调传错格式,比如要求传数组结果却给了字符串,代码很容易炸锅。TypeScript 能帮我们提前堵住这类坑,核心就是给回调加上“类型约束”。
先搞懂最基础的回调类型
假设我们要做一个“水果采购”的小功能:先去市场买水果,等买完了,再用回调告诉老板“买完啦,接下来要算账”。用普通 JavaScript 写的话,函数很灵活,但没人能保证传的回调是对的:

`javascript
// 普通JS写法,容易出错
function buyFruit(fruit, callback) {
console.log(买了${fruit});
callback(); // 老板要求的是“买完”,但传回调的人可能写错
}
// 没问题的情况
buyFruit("草莓", () => console.log("开始算账"));
// 容易错的情况:传了数字,完全不是函数
buyFruit("香蕉", 123);
`
换成 TypeScript,只要给回调加个类型注解,就能提前拦住错的:
`typescript
// 给callback加了“必须是无参数、无返回值的函数”的约束
function buyFruit(fruit: string, callback: () => void) {
console.log(买了${fruit});
callback();
}
// 正确:传了符合要求的函数
buyFruit("草莓", () => console.log("开始算账"));
// 错误:TS会直接标红,说“你传的123不是函数”
buyFruit("香蕉", 123);
`
这就是回调类型的基础作用:明确“回调该长什么样”,避免传错。
带参数的回调怎么写?
实际工作里,回调经常要拿前面函数的结果用。比如买完水果要把买了多少斤告诉回调,这时候就得给回调加“接收参数”的类型。
比如我们要做个“点外卖”的功能:下单后,回调要拿到“外卖费”来显示总价格。这时候回调需要接收一个数字参数,TypeScript 可以这么写:
`typescript
// callback要接收一个number类型的参数,返回void
function orderTakeout(food: string, callback: (deliveryFee: number) => void) {
console.log(下单了${food});
const fee = 5; // 假设外卖费固定5元
callback(fee); // 把外卖费传给回调
}
// 正确:回调接收参数,TS自动知道参数是number
orderTakeout("披萨", (fee) => console.log(总价格:100 + ${fee} = 105元));
// 错误:回调没传参数,TS会提示“缺少参数”
orderTakeout("汉堡", (fee) => console.log(总价格:100元));
`
这里的 (deliveryFee: number) => void 就是“带数字参数的无返回函数”,正好对应老板要的“拿到外卖费再算总价”的需求。
回调返回值也能加类型
有时候回调会返回结果,比如我们要做“批量打印名片”的功能:打印完每张名片,回调要返回“是否打印成功”,最后把所有结果收集起来。这时候需要给回调的返回值加类型。
TypeScript 里可以这么写:
`typescript
// callback接收名片名字,返回boolean(是否成功),最后collectResults会收集所有结果
function printCards(names: string[], callback: (name: string) => boolean) {
const results: boolean[] = [];
for (const name of names) {
const success = callback(name);
results.push(success);
}
return results;
}
// 正确:回调返回boolean,符合要求
const results = printCards(["张三", "李四"], (name) => {
console.log(打印${name}的名片);
return name.length > 2; // 名字超过2字才打印成功
});
console.log(results); // [true, true]
`
要是回调返回了字符串,TS会直接标红,说“返回类型不符合要求”,避免后续用结果时出错。
用类型别名简化复杂回调
如果回调的类型太复杂,比如要同时接收多个参数,还带返回值,反复写会很麻烦。这时候可以用 TypeScript 的类型别名,把回调的类型存成一个变量,方便复用。
比如我们要做“不同店铺的优惠计算”,每个店铺的回调都要接收“原价”和“会员等级”,返回“优惠后的价格”:
`typescript
// 把回调的类型存成PriceCalculator,方便复用
type PriceCalculator = (originalPrice: number, memberLevel: string) => number;
function calculateDiscount(price: number, calculator: PriceCalculator) {
const memberLevel = "黄金"; // 假设当前会员等级
return calculator(price, memberLevel);
}
// 用类型别名传回调,清晰不容易错
const goldDiscount: PriceCalculator = (price, level) => {
return level === "黄金" ? price * 0.8 : price;
};
console.log(calculateDiscount(100, goldDiscount)); // 输出80
`
这样不管要加多少种优惠计算方式,只要 PriceCalculator 类型不变,就不会传错回调格式。
简单来说,TypeScript 做回调类型,就是给“要传给别人的函数”定好规矩,从根源上减少代码出错,尤其适合多人协作的项目,哪怕新手写回调,也能通过类型提示快速知道该怎么写。