TypeScript 函数详解
TypeScript 的函数语法与 JavaScript 基本一致,但增加了强大的类型支持,包括参数类型、返回值类型、可选参数、默认参数、剩余参数、重载等。这些特性让函数更安全、更易维护。
1. 基本函数声明与表达式
// 函数声明(Function Declaration)
function add(a: number, b: number): number {
return a + b;
}
// 函数表达式(Function Expression)
const subtract: (x: number, y: number) => number = (x, y) => x - y;
// 箭头函数(Arrow Function)——推荐用于简短函数
const multiply = (a: number, b: number): number => a * b;
TS 优势:
- 参数和返回值必须指定类型(或通过推断)。
- 编译时检查类型匹配,避免运行时错误。
add(10, "20"); // 编译错误:参数类型不匹配
2. 可选参数与默认参数
// 可选参数(用 ? 表示,必须放在必选参数后面)
function greet(name: string, greeting?: string): string {
return `${greeting ?? "Hi"} ${name}`;
}
greet("Alice"); // "Hi Alice"
greet("Bob", "Hello"); // "Hello Bob"
// 默认参数(ES6+ 支持)
function log(message: string = "Info"): void {
console.log(message);
}
log(); // "Info"
log("Error"); // "Error"
3. 剩余参数(Rest Parameters)
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
sum(1, 2, 3, 4); // 10
sum(); // 0
剩余参数类型必须是数组类型。
4. 函数重载(Function Overloading)
TypeScript 支持函数重载:同一个函数名,根据不同参数类型/数量提供不同实现。
function format(value: string): string;
function format(value: number, digits: number): string;
function format(value: any, digits?: any): string {
if (typeof value === "string") {
return value.toUpperCase();
}
if (typeof value === "number") {
return value.toFixed(digits ?? 2);
}
return String(value);
}
format("hello"); // "HELLO"
format(3.14159, 2); // "3.14"
规则:
- 先写多个重载签名(只有类型,没有实现)。
- 最后写实际实现函数(兼容所有重载)。
5. this 类型处理
箭头函数会捕获外部 this,普通函数在 TS 中可显式声明 this 参数。
interface User {
name: string;
}
function showName(this: User) {
console.log(this.name);
}
const user: User = { name: "Alice" };
showName.call(user); // "Alice"
6. void、never 与函数返回值
// void:函数无返回值(返回 undefined 也算 void)
function warn(): void {
console.log("Warning!");
}
// never:函数永远不会正常返回(抛错或无限循环)
function error(msg: string): never {
throw new Error(msg);
}
function infiniteLoop(): never {
while (true) {}
}
7. 函数类型定义
可以单独定义函数类型,然后赋值。
// 类型别名
type BinaryOperation = (a: number, b: number) => number;
const add: BinaryOperation = (x, y) => x + y;
const divide: BinaryOperation = (x, y) => {
if (y === 0) throw new Error("除零");
return x / y;
};
8. 异步函数(async/await)
async function fetchData(url: string): Promise<string> {
const response = await fetch(url);
if (!response.ok) throw new Error("网络错误");
return await response.text();
}
// 使用
fetchData("https://api.example.com")
.then(data => console.log(data))
.catch(err => console.error(err));
返回类型通常为 Promise<T>。
9. 最佳实践建议
| 建议 | 示例说明 |
|---|---|
| 始终标注返回值类型 | : string 而非省略(提升可读性) |
参数尽量避免 any | 用具体类型或泛型替代 |
| 使用箭头函数作为回调 | 避免 this 指向问题 |
| 复杂函数优先使用重载 | 提供更好的类型提示 |
开启 noImplicitAny | 强制显式类型,避免隐式 any |
| 短函数用箭头,长函数用声明 | 可读性更好 |
小结:函数声明速查表
| 类型 | 语法示例 | 适用场景 |
|---|---|---|
| 普通函数声明 | function fn(a: number): string {} | 复杂逻辑 |
| 箭头函数 | const fn = (a: number) => string | 简短、回调 |
| 可选/默认参数 | function fn(name: string, age?: number = 18) | 灵活调用 |
| 剩余参数 | function fn(...args: string[]) | 不定参数 |
| 函数重载 | 多签名 + 一个实现 | 多态行为 |
| async 函数 | async function fn(): Promise<T> | 异步操作 |
如果您想深入某个部分(如泛型函数、函数装饰器、高阶函数、或 React 中的函数组件),或者需要完整示例代码,请告诉我!