TypeScript 函数
函数是 JS/TS 里组织代码的基本单位。给函数加上类型,是 TS 最核心、最高频的用法——它让你一眼看出函数接受什么参数、返回什么结果,调用时传错立刻报错。这一章讲清楚函数类型的所有写法。
1. 参数与返回值类型
给函数标类型,就是给每个参数加 : 类型,给括号后加返回类型:
// 给函数标类型:参数 + 返回值
function add(a: number, b: number): number {
return a + b;
}
// 箭头函数同样
const mul = (a: number, b: number): number => a * b;
// 调用时传错类型会报错
add(1, "2");
// ❌ 类型"string"的参数不能赋给类型"number"
// 返回值类型通常能推断,可以省略
const sub = (a: number, b: number) => a - b; // 推断返回 number返回值类型大部分时候能自动推断(如 sub),可以省略。但函数参数必须显式标注(因为没有初始值,TS 推断不出来)。这是一个关键原则。
2. void 与 never
两个特殊的返回类型:void 表示"无返回值",never 表示"永远不会正常返回":
// 没有返回值的函数用 void
function log(msg: string): void {
console.log(msg);
}
// 函数中途抛异常或无限循环,用 never
function fail(msg: string): never {
throw new Error(msg);
}3. 可选参数、默认参数、剩余参数
这三者和 JS 的写法一致,只是配合类型时有细节:
// 可选参数:加 ?(必须在必填参数后面)
function greet(name: string, greeting?: string): string {
return `${greeting ?? "你好"}, ${name}`;
}
greet("小明"); // 你好, 小明
greet("小明", "嗨"); // 嗨, 小明
// 默认参数:有默认值就不需要 ?
function greet2(name: string, greeting: string = "你好"): string {
return `${greeting}, ${name}`;
}
// 剩余参数:用 ... 收集成数组
function sum(...nums: number[]): number {
return nums.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10一个重要规则:可选参数必须排在必填参数后面(和 JS 一样)。有默认值的参数本质上就是可选的,不需要再加 ?。
4. 函数类型别名
当函数被当作值传递(比如回调、回调数组)时,常用 type 给函数类型起名字,复用更方便:
// 函数类型:用 type 别名定义
type Greet = (name: string, age: number) => string;
const greet: Greet = (name, age) => {
return `你好 ${name}, ${age} 岁`;
};
// 注意:实现时不用再写参数类型,由 Greet 推断
// 回调函数类型很常见
type Callback = (data: string) => void;
function fetchData(cb: Callback): void {
cb("模拟数据");
}5. 函数重载
JS 的函数可以"根据传入参数不同,行为不同"(比如 format(3.14) 返回数字格式化、format("hi") 返回字符串裁剪)。TS 用函数重载来精确描述这种多行为:
// 函数重载:同一个函数有多种调用签名
// 1. 先写几条"重载签名"(只写类型,不写实现)
function format(input: number): string;
function format(input: string): string;
// 2. 再写一条"实现签名"(要兼容所有重载)
function format(input: number | string): string {
if (typeof input === "number") {
return input.toFixed(2);
}
return input.trim();
}
format(3.14159); // "3.14"
format(" hi "); // "hi"
// format(true); // ❌ 报错:没有匹配的重载重载的关键是:先写若干条重载签名(只标类型),最后写一条实现签名(要兼容所有重载)。调用时 TS 会按重载签名匹配。函数重载是 TS 进阶内容,初学阶段先了解。
6. this 类型(进阶)
在严格模式下,函数内部的 this 默认是 unknown。对于事件回调这类需要约束 this 的场景,TS 允许用虚参标注 this 类型:
// 回调里的 this 类型(进阶,了解即可)
interface Button {
onClick(cb: (this: Button, e: string) => void): void;
}
// 第一个参数 this 是"虚参",运行时不传,只用于类型检查
// 它约束函数内部 this 的类型,常用于事件处理this 是个特殊参数——它写在第一个位置,但运行时不传入,只用于编译期检查。初学阶段可以跳过,知道有这回事即可。
7. 实战示例:类型安全的工具函数
把上面学的组合起来,写一个简单的工具函数:
小结
函数类型的要点:参数必须显式标注、返回值能推断就省略、无返回值用 void、可选参数加 ?、函数类型用 type 起别名。下一篇我们挑战 TS 最"高级但必修"的概念——泛型。
← 上一篇 TypeScript 类型别名
下一篇 TypeScript 泛型 →