TypeScript - 函数
TypeScript - 函数
Section titled “TypeScript - 函数”函数(Functions)是创建可读、可维护和可重用代码的基本构建块。它们封装了一组旨在执行特定任务的语句。将代码组织到函数中使程序更具逻辑性且易于管理。
在 TypeScript 中,就像 JavaScript 一样,函数是第一类公民(first-class citizens)。它们可以被定义、作为参数传递、从其他函数返回以及赋值给变量。
TypeScript 通过为参数和返回值添加显式的类型注解 (type annotations) 来增强 JavaScript 函数,提供编译时安全 (compile-time safety)。
| 概念 (Concept) | 描述 (Description) |
|---|---|
| 定义函数 (Defining a Function) | 指定函数的名称、参数(带类型)、返回值类型,以及要执行的代码块(函数体)。 |
| 调用函数 (Calling a Function) | 通过函数的名称后跟括号 () 来调用函数,并传递任何必需的参数 (arguments)。 |
| 返回值 (Return Values) | 函数可以使用 return 关键字返回一个值。返回值的类型应与函数声明的返回值类型匹配。不返回值的函数其返回值类型为 void。 |
| 参数 (Parameters) 与 实参 (Arguments) | 参数是在函数定义中列出的变量。实参是在调用函数时传递给函数的实际值。 |
函数语法 (Function Syntax)
Section titled “函数语法 (Function Syntax)”TypeScript 支持几种定义函数的方式:
1. 命名函数声明 (Named Function Declaration)
Section titled “1. 命名函数声明 (Named Function Declaration)”function greet(name: string): string { return `Hello, ${name}!`;}
function logMessage(message: string): void { console.log(message);}
let greeting = greet("Alice"); // greeting 的类型被推断为 stringlogMessage(greeting);2. 函数表达式 (匿名函数) (Function Expression (Anonymous Function))
Section titled “2. 函数表达式 (匿名函数) (Function Expression (Anonymous Function))”将函数赋值给一个变量。函数本身可以是匿名的。
const add = function(x: number, y: number): number { return x + y;};
let sum: number = add(10, 5);3. 箭头函数表达式 (Arrow Function Expression)
Section titled “3. 箭头函数表达式 (Arrow Function Expression)”函数表达式的简洁语法,特别适用于内联函数和回调函数。箭头函数捕获封闭上下文(词法作用域 this)的 this 值。
const multiply = (x: number, y: number): number => { return x * y;};
// 简洁函数体(单个表达式,隐式返回)const subtract = (x: number, y: number): number => x - y;
// 没有参数的箭头函数const logTime = (): void => { console.log(new Date()); };
// 有一个参数的箭头函数(括号可选)const square = (x: number): number => x * x;// const square = x => x * x; // 如果可能,类型会被推断,但显式类型通常更好
let product: number = multiply(4, 6);logTime();函数参数 (Function Parameters)
Section titled “函数参数 (Function Parameters)”可选参数 (Optional Parameters)
Section titled “可选参数 (Optional Parameters)”参数可以通过在其名称后添加 ? 来标记为可选。可选参数必须出现在必需参数之后。如果未提供可选参数,其值为 undefined。
function buildName(firstName: string, lastName?: string): string { if (lastName) { return `${firstName} ${lastName}`; } else { return firstName; }}
let name1 = buildName("Bob"); // 输出: Boblet name2 = buildName("Bob", "Adams"); // 输出: Bob Adams
console.log(name1);console.log(name2);默认参数 (Default Parameters)
Section titled “默认参数 (Default Parameters)”你可以为参数提供默认值。如果未为默认参数提供实参(或传递了 undefined),则使用默认值。默认参数不一定需要出现在必需参数之后,但这样做通常能提高可读性。
function calculateRate(price: number, rate: number = 0.05): number { return price * rate;}
let amount1 = calculateRate(1000); // 使用默认比率 0.05 -> 50let amount2 = calculateRate(1000, 0.1); // 使用提供的比率 0.1 -> 100
console.log(amount1);console.log(amount2);注意:参数不能同时是可选参数 (?) 并拥有默认值。
剩余参数 (Rest Parameters)
Section titled “剩余参数 (Rest Parameters)”使用剩余语法 (...) 将多个实参收集到一个数组参数中。剩余参数必须是函数定义中的最后一个参数,并且必须是数组类型。
function sumAll(...numbers: number[]): number { let total = 0; for (const num of numbers) { total += num; } return total;}
let total1 = sumAll(1, 2, 3); // 输出: 6let total2 = sumAll(10, 20, 30, 40); // 输出: 100
console.log(total1);console.log(total2);函数重载 (Function Overloads)
Section titled “函数重载 (Function Overloads)”函数重载允许为一个函数名定义多个函数签名(参数类型和返回值类型),后跟一个实现函数体。该实现函数体的签名必须与所有重载签名兼容。TypeScript 使用重载签名来对函数调用进行类型检查。
// 重载签名function process(value: string): string;function process(value: number): number;function process(value: boolean): boolean;
// 实现签名(必须与重载兼容)function process(value: string | number | boolean): string | number | boolean { if (typeof value === 'string') { return value.toUpperCase(); } if (typeof value === 'number') { return value * 2; } return !value;}
let result1: string = process("data"); // 正确推断为 string 类型let result2: number = process(10); // 正确推断为 number 类型let result3: boolean = process(true); // 正确推断为 boolean 类型
console.log(result1); // 输出: DATAconsole.log(result2); // 输出: 20console.log(result3); // 输出: false
// let errorResult = process({ a: 1 }); // 错误: 没有重载匹配此调用。重载对于函数基于传递的实参类型或数量表现不同行为时非常有用。
其他函数概念 (Other Function Concepts)
Section titled “其他函数概念 (Other Function Concepts)”- **
this关键字:**行为取决于函数如何被调用。箭头函数拥有词法作用域的this,而标准函数通常依赖于调用 site(例如,对象方法、独立调用)。TypeScript 提供了一些方式来显式地为this添加类型。 - **递归 (Recursion):**函数调用自身。需要一个基本情况 (base case) 来防止无限循环。
- **高阶函数 (Higher-Order Functions):**接受其他函数作为实参或返回函数的函数。
- **泛型 (Generics):**创建可重用函数,这些函数可以处理各种类型同时保持类型安全(在更高级主题中介绍)。
最佳实践 (Best Practices)
Section titled “最佳实践 (Best Practices)”- 始终为参数和返回值提供显式的类型注解,除非类型推断 (type inference) 显而易见且微不足道。
- 由于简洁的语法和词法作用域的
this,优先为回调函数和简短简单的函数使用箭头函数。 - 除非你明确需要重新赋值该变量,否则为函数表达式使用
const。 - 让函数专注于单一任务(单一职责原则 Single Responsibility Principle)。
- 当函数确实根据类型处理不同的参数模式时,使用函数重载,但避免过于复杂的重载集合。