TypeScript 函数
函数是 JavaScript 的核心构建块,TypeScript 为函数添加了类型支持。
函数类型
基本类型注解
// 函数声明
function add(a: number, b: number): number {
return a + b;
}
// 函数表达式
const multiply = function(a: number, b: number): number {
return a * b;
};
// 箭头函数
const divide = (a: number, b: number): number => {
return a / b;
};
// 简写箭头函数
const square = (n: number): number => n * n;
解释:参数列表中的每个参数都需要类型注解,返回值类型可以省略(TypeScript 会自动推断)。
函数类型表达式
// 定义函数类型
type MathOperation = (a: number, b: number) => number;
// 使用函数类型
const subtract: MathOperation = (a, b) => a - b;
const power: MathOperation = (a, b) => a ** b;
// 作为参数类型
function calculate(a: number, b: number, operation: MathOperation): number {
return operation(a, b);
}
calculate(10, 5, subtract); // 5
calculate(2, 3, power); // 8
参数类型
可选参数
function greet(name: string, greeting?: string): string {
if (greeting) {
return `${greeting}, ${name}!`;
}
return `Hello, ${name}!`;
}
greet("张三"); // "Hello, 张三!"
greet("张三", "你好"); // "你好, 张三!"
解释:可选参数使用 ? 标记,必须放在必需参数之后。
默认参数
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
greet("张三"); // "Hello, 张三!"
greet("张三", "你好"); // "你好, 张三!"
// 默认参数不需要放在最后
function createPoint(x: number, y = 0, z = 0): [number, number, number] {
return [x, y, z];
}
解释:默认参数在调用时可以省略,默认参数会自动推断类型,无需显式注解。
剩余参数
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
sum(1, 2, 3); // 6
sum(1, 2, 3, 4, 5); // 15
// 结合其他参数
function log(level: string, ...messages: string[]): void {
console.log(`[${level}]`, ...messages);
}
log("INFO", "服务器启动", "端口 3000");
// [INFO] 服务器启动 端口 3000
解构参数
interface Point {
x: number;
y: number;
}
// 解构对象参数
function printPoint({ x, y }: Point): void {
console.log(`(${x}, ${y})`);
}
printPoint({ x: 10, y: 20 }); // "(10, 20)"
// 解构数组参数
function printCoordinates([x, y]: [number, number]): void {
console.log(`X: ${x}, Y: ${y}`);
}
printCoordinates([10, 20]); // "X: 10, Y: 20"
函数重载
函数重载允许同一个函数接受不同类型或数量的参数。
基本重载
// 重载签名
function convert(value: number): string;
function convert(value: string): number;
function convert(value: boolean): string;
// 实现签名
function convert(value: number | string | boolean): string | number {
if (typeof value === "number") {
return value.toString();
} else if (typeof value === "string") {
return parseInt(value, 10);
} else {
return value ? "true" : "false";
}
}
// 使用
const numStr: string = convert(123); // "123"
const strNum: number = convert("456"); // 456
const boolStr: string = convert(true); // "true"
解释:重载签名定义函数的不同调用方式,实现签名必须兼容所有重载签名。
实际应用示例
// 创建元素
function createElement(tag: "a"): HTMLAnchorElement;
function createElement(tag: "canvas"): HTMLCanvasElement;
function createElement(tag: "table"): HTMLTableElement;
function createElement(tag: string): HTMLElement;
function createElement(tag: string): HTMLElement {
return document.createElement(tag);
}
// 事件处理
function on(element: HTMLElement, event: "click", handler: (e: MouseEvent) => void): void;
function on(element: HTMLElement, event: "input", handler: (e: Event) => void): void;
function on(element: HTMLElement, event: string, handler: (e: Event) => void): void {
element.addEventListener(event, handler);
}
方法重载
class Calculator {
// 重载:不同参数数量
add(a: number, b: number): number;
add(a: number, b: number, c: number): number;
add(a: number, b: number, c?: number): number {
if (c !== undefined) {
return a + b + c;
}
return a + b;
}
}
const calc = new Calculator();
calc.add(1, 2); // 3
calc.add(1, 2, 3); // 6
this 类型
指定 this 类型
interface User {
name: string;
greet(this: User): void;
}
const user: User = {
name: "张三",
greet() {
console.log(`Hello, I'm ${this.name}`);
}
};
user.greet(); // "Hello, I'm 张三"
// const greetFn = user.greet;
// greetFn(); // 错误:this 必须是 User 类型
解释:使用 this 参数可以确保方法在正确的上下文中调用。
箭头函数保留 this
class Person {
constructor(private name: string) {}
// 普通方法 - this 可能丢失
greetNormal() {
console.log(`Hello, I'm ${this.name}`);
}
// 箭头函数 - this 绑定到实例
greetArrow = () => {
console.log(`Hello, I'm ${this.name}`);
};
}
const person = new Person("张三");
const { greetNormal, greetArrow } = person;
// greetNormal(); // 错误:this 是 undefined
greetArrow(); // "Hello, I'm 张三"
返回类型
显式返回类型
// 显式声明返回类型
function createPoint(x: number, y: number): { x: number; y: number } {
return { x, y };
}
// 使用接口
interface Point {
x: number;
y: number;
}
function createPoint2(x: number, y: number): Point {
return { x, y };
}
返回类型推断
// TypeScript 自动推断返回类型
function add(a: number, b: number) {
return a + b; // 推断为 number
}
// 复杂类型推断
function getUser() {
return {
name: "张三",
age: 25
};
// 推断为 { name: string; age: number; }
}
void 返回类型
// 没有返回值的函数
function log(message: string): void {
console.log(message);
}
// 可以返回 undefined 或 null(非严格模式)
function doNothing(): void {
return undefined;
}
never 返回类型
// 永远不会正常返回
function fail(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {}
}
函数作为值
回调函数
// 定义回调类型
type Callback = (data: string) => void;
function fetchData(url: string, callback: Callback): void {
// 模拟异步获取数据
setTimeout(() => {
callback("获取的数据");
}, 1000);
}
fetchData("/api/data", (data) => {
console.log(data);
});
高阶函数
// 接受函数,返回函数
function debounce<T extends (...args: any[]) => any>(
func: T,
wait: number
): (...args: Parameters<T>) => void {
let timeout: ReturnType<typeof setTimeout>;
return function(...args: Parameters<T>) {
clearTimeout(timeout);
timeout = setTimeout(() => func(...args), wait);
};
}
// 使用
const debouncedLog = debounce((message: string) => {
console.log(message);
}, 300);
函数类型推断
参数类型推断
// 泛型函数 - 类型推断
function identity<T>(arg: T): T {
return arg;
}
const str = identity("hello"); // T 推断为 string
const num = identity(123); // T 推断为 number
// 显式指定类型
const explicit = identity<string>("hello");
条件返回类型
function getValue<T extends string | number>(
value: T
): T extends string ? string : number {
return value as any;
}
const strResult = getValue("hello"); // string
const numResult = getValue(123); // number
小结
本章我们学习了 TypeScript 函数:
- 函数类型注解
- 可选参数、默认参数、剩余参数
- 参数解构
- 函数重载
- this 类型
- 返回类型(void、never)
- 函数作为值传递
练习
- 定义一个函数,接受可选的问候语参数
- 实现一个函数重载,接受字符串或数组并返回其长度
- 创建一个高阶函数,实现节流功能
- 定义一个事件处理函数类型