Skip to content

在任何编程语言中,函数都是构建逻辑的基本单元。它们帮助我们封装代码、实现复用并构建复杂的应用。当我们进入 TypeScript 的世界,函数的能力得到了进一步的增强——这主要归功于其强大的类型系统。

在日常开发中,为函数精确定义输入和输出是保障代码健壮性的关键。接下来,我们将一起探讨 TypeScript 是如何通过类型注解、可选参数和默认参数,来优化函数定义的。

为函数添加类型注解

在 TypeScript 中,最直接的增强是为函数的参数和返回值添加明确的类型注解。这不仅是 TypeScript 的核心特性,也是编写高质量、可维护代码的基石。

它的语法非常直观:

  • 在参数名后使用冒号 (:) 来指定该参数的类型。
  • 在函数参数列表的括号后使用冒号 (:) 来指定函数的返回值类型。

让我们来看一个简单的例子。假设我们需要一个函数,它接收两个数字作为参数,并返回它们的和。

typescript
function add(a: number, b: number): number {
  return a + b;
}

通过这种方式,我们向 TypeScript 编译器以及其他开发者清晰地传达了此函数的“契约”:

  1. 参数 a 必须是 number 类型。
  2. 参数 b 必须是 number 类型。
  3. 该函数必须返回一个 number 类型的值。

如果我们在调用 add 函数时传入了非数字类型的参数,TypeScript 编译器会在编译阶段就立刻抛出错误,从而避免了在运行时可能出现的意外行为。这种“前置”的错误捕获机制,是 TypeScript 相比于原生 JavaScript 的一大优势。

赋予函数更多灵活性:可选参数与默认参数

虽然严格的类型定义是好事,但在某些场景下,我们也需要函数具备一定的灵活性。例如,一个函数的某些参数并非每次调用都需要传递。针对这种情况,TypeScript 提供了可选参数和默认参数两种实用的机制。

1. 可选参数

当我们希望函数的某个参数可以被“省略”时,可以使用可选参数。语法是在参数名后、冒号前添加一个问号 (?)

我们来设想一个向用户打招呼的函数。这个函数必须知道用户的名字,但问候语可以是可选的。

typescript
function greet(name: string, salutation?: string): string {
  if (salutation) {
    return `${salutation}, ${name}!`;
  } else {
    return `Hello, ${name}!`;
  }
}

// 两种有效的调用方式
console.log(greet("Alice")); // 输出: Hello, Alice!
console.log(greet("Bob", "Good morning")); // 输出: Good morning, Bob!

需要注意的是,当一个可选参数未被传递时,它在函数内部的值是 undefined。因此,我们需要在函数体内进行相应的逻辑判断。

此外,一个重要的规则是:可选参数必须位于必选参数之后。这是为了让 TypeScript 能够正确地将传入的参数与函数定义中的参数对应起来。

2. 默认参数

默认参数与可选参数解决的是类似的问题,但实现方式略有不同。它允许我们为参数提供一个默认值,当调用者没有传递该参数时,函数将自动使用这个预设的值。

语法非常简洁,直接在参数声明后使用等号 (=) 即可。

我们来重构一下上面的 greet 函数,这次使用默认参数:

typescript
function greetWithDefault(name: string, salutation: string = "Hello"): string {
  return `${salutation}, ${name}!`;
}

// 两种调用方式及其结果
console.log(greetWithDefault("Alice")); // 输出: Hello, Alice!
console.log(greetWithDefault("Bob", "Good morning")); // 输出: Good morning, Bob!

使用默认参数的好处是代码更显简洁。我们不再需要在函数体内检查参数是否为 undefined,因为 TypeScript 已经保证了 salutation 参数总会有一个 string 类型的值。

当一个参数被赋予了默认值,它实际上也变成了“可选”的。与可选参数不同的是,带有默认值的参数不强制要求必须放在参数列表的末尾。然而,为了保持代码的可读性和一致性,通常我们还是建议将它们放在必选参数之后。

总结

通过本次梳理,我们可以看到 TypeScript 为函数带来了显著的改进:

  • 类型注解:通过为参数和返回值添加类型,我们极大地提升了代码的明确性和可靠性,能在开发早期就发现潜在的类型错误。
  • 可选参数 (?):提供了定义非必需参数的灵活性,调用时可以省略这些参数。
  • 默认参数 (=):在参数未传递时为其提供预设值,简化了函数内部的逻辑处理,并使代码更加清晰。

掌握这些特性,是编写现代化、高健壮性 TypeScript 代码的基础。在日常开发中,结合运用这些工具,我们可以构建出既灵活又安全的函数,从而为整个应用的质量提供坚实的保障。

不知道说啥了很无语了