TypeScript 如何在函数中支持可选参数?


TypeScript 是 JavaScript 的一个静态类型超集,它为该语言添加了静态类型功能。TypeScript 的关键特性之一是它能够在函数声明中提供可选参数,允许开发人员定义参数在函数调用期间可能提供也可能不提供的函数。这种灵活性增强了代码的可重用性并简化了函数调用,从而产生了更易于维护和表达的代码。

在本教程中,我们将探讨 TypeScript 如何在函数中支持可选参数,涵盖语法、优点和一些实际示例。

语法

要在 TypeScript 函数中定义可选参数,可以在函数声明中参数名称后使用问号 (?) 符号。这表示该参数是可选的,可以在调用函数时省略。带有可选参数的函数的通用语法如下所示:

function functionName(param1: type, param2?: type) {
   // Function body
}

在上面的语法中,param1 是必需参数,而 param2 是可选参数。问号表示 param2 不是强制性的,可以在调用函数时省略。可选参数只能放在参数列表的末尾。

可选参数的优点

  • 灵活性 - 可选参数通过允许开发人员在调用函数时省略某些参数,从而为函数调用提供了灵活性。这在某些情况下可能很有用,在这些情况下参数可能并不总是必要的,从而导致更简洁和更简洁的代码。

  • 代码可重用性 - 可选参数能够创建可在多种情况下重用的函数。通过使参数可选,开发人员可以定义适应各种用例的通用函数,而无需为每个特定用例定义单独的函数。

  • 改进的可读性 - 可选参数可以通过清楚地指示哪些参数是必需的以及哪些参数是可选的来增强代码的可读性。这使开发人员能够更轻松地理解函数的预期用法,并使代码更具自解释性。

示例

示例 1:基本可选参数

在下面的示例中,greet 函数有一个可选参数 greeting。如果在函数调用期间提供了问候语,它将包含在输出中。如果省略了问候语,则将使用默认问候语。

function greet(name: string, greeting?: string) {
   if (greeting) {
      console.log(`${greeting}, ${name}!`);
   } else {
      console.log(`Hello, ${name}!`);
   }
}
greet("Alice");  // Output: Hello, Alice!
greet("Bob", "Hi");  // Output: Hi, Bob!

编译后,它将生成以下 JavaScript 代码:

function greet(name, greeting) {
   if (greeting) {
      console.log("".concat(greeting, ", ").concat(name, "!"));
   }
   else {
      console.log("Hello, ".concat(name, "!"));
   }
}
greet("Alice"); // Output: Hello, Alice!
greet("Bob", "Hi"); // Output: Hi, Bob!

输出

以上代码将产生以下输出:

Hello, Alice!
Hi, Bob!

示例 2:具有默认值的可选参数

在此示例中,calculateArea 函数有两个参数,width 和 height。height 参数是可选的,并且具有默认值 10。如果在函数调用期间未提供 height,则默认为 10。

function calculateArea(width: number, height: number = 10) {
   return width * height;
}

console.log(`The area with 5 input is: ${calculateArea(5)}`); 
console.log(`The area with 5, 8 input is: ${calculateArea(5, 8)}`);

编译后,它将生成以下 JavaScript 代码:

function calculateArea(width, height) {
   if (height === void 0) { height = 10; }
   return width * height;
}
console.log("The area with 5 input is: ".concat(calculateArea(5)));
console.log("The area with 5, 8 input is: ".concat(calculateArea(5, 8)));

输出

The area with 5 input is: 50
The area with 5, 8 input is: 40

示例 3:回调函数中的可选参数

在此示例中,fetchData 函数接受一个回调函数作为可选参数。fetchData 方法被定义为模拟从给定 URL 获取数据的过程。回调函数可以在有或没有错误参数的情况下调用,具体取决于数据获取操作期间是否发生错误。

function fetchData(url: string, callback: (data: any, error?: Error) => void) {
   // Simulating data fetching from the URL
   const data = { id: 1, name: "John Doe" };
   // Invoke the callback function with the fetched data
   callback(data);
   // Simulating the presence of an error
   const error = new Error("Oh an error occurred!");
   callback(data, error);
}
// Example usage:
fetchData("https://example.com/data", (data, error) => {
   if (error) {
      console.error("An error occurred:", error);
   } else {
      console.log("Fetched data:", data, "

"); } });

编译后,它将生成以下 JavaScript 代码:

function fetchData(url, callback) {
   // Simulating data fetching from the URL
   var data = { id: 1, name: "John Doe" };
   // Invoke the callback function with the fetched data
   callback(data);
   // Simulating the presence of an error
   var error = new Error("Oh an error occurred!");
   callback(data, error);
}
// Example usage:
fetchData("https://example.com/data", function (data, error) {
   if (error) {
      console.error("An error occurred:", error);
   }
   else {
      console.log("Fetched data:", data, "

"); } });

输出

Fetched data: { id: 1, name: 'John Doe' } 

An error occurred: Error: Oh an error occurred!
   at fetchData (/home/cg/root/6477262d95bb2/main.js:7:17)
   at Object.<anonymous> (/home/cg/root/6477262d95bb2/main.js:11:1)
   at Module._compile (internal/modules/cjs/loader.js:999:30)
   at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
   at Module.load (internal/modules/cjs/loader.js:863:32)
   at Function.Module._load (internal/modules/cjs/loader.js:708:14)
   at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
   at internal/main/run_main_module.js:17:47

第二个带有错误参数的调用会导致终端出现错误,这符合预期。

示例 4:可选对象属性

在此示例中,Person 接口具有可选属性,例如 ageemaildisplayPerson 函数可以处理符合 Person 接口的对象,无论可选属性是否存在。

interface Person {
   name: string;
   age?: number;
   email?: string;
}

function displayPerson(person: Person) {
   console.log(`Name: ${person.name}`);
   if (person.age) {
      console.log(`Age: ${person.age}`);
   }
   if (person.email) {
      console.log(`Email: ${person.email}`);
   }
}

const alice: Person = { name: "Alice" };
const bob: Person = { name: "Bob", age: 25, email: "[email protected]" };

displayPerson(alice);
displayPerson(bob);

编译后,它将生成以下 JavaScript 代码:

function displayPerson(person) {
   console.log("Name: ".concat(person.name));
   if (person.age) {
      console.log("Age: ".concat(person.age));
   }
   if (person.email) {
      console.log("Email: ".concat(person.email));
   }
}
var alice = { name: "Alice" };
var bob = { name: "Bob", age: 25, email: "[email protected]" };
displayPerson(alice);
displayPerson(bob);

输出

Name: Alice
Name: Bob
Age: 25
Email: [email protected]

示例 5:类方法中的可选参数

在此示例中,我们有一个 Rectangle 类,它具有一个 calculateArea 方法。calculateArea 方法有一个可选参数 unit,它表示面积的度量单位。如果提供了单位,它们将包含在输出中。如果省略了单位,则默认行为将显示没有单位的面积。这允许根据调用者的特定需求灵活使用 calculateArea 方法。

class Rectangle {
   private width: number;
   private height: number;

   constructor(width: number, height: number) {
      this.width = width;
      this.height = height;
   }

   calculateArea(units?: string): number {
      const area = this.width * this.height;
      if (units) {
         console.log(`Area: ${area} ${units}`);
      } else {
         console.log(`Area: ${area}`);
      }
      return area;
   }
}

const rectangle1 = new Rectangle(5, 10);
rectangle1.calculateArea();  // Output: Area: 50
rectangle1.calculateArea("sq. units");  // Output: Area: 50 sq. units

编译后,它将生成以下 JavaScript 代码:

var Rectangle = /** @class */ (function () {
   function Rectangle(width, height) {
      this.width = width;
      this.height = height;
   }
   Rectangle.prototype.calculateArea = function (units) {
      var area = this.width * this.height;
      if (units) {
         console.log("Area: ".concat(area, " ").concat(units));
      }
      else {
         console.log("Area: ".concat(area));
      }
      return area;
   };
   return Rectangle;
}());
var rectangle1 = new Rectangle(5, 10);
rectangle1.calculateArea(); // Output: Area: 50
rectangle1.calculateArea("sq. units"); // Output: Area: 50 sq. units

输出

以上代码将产生以下输出:

Area: 50
Area: 50 sq. units

结论

TypeScript 在函数中对可选参数的支持增强了代码的灵活性和可重用性,并提高了可读性。通过使某些参数可选,开发人员可以创建可以使用或不使用特定参数调用的函数。此功能允许更简洁和更适应的代码,从而更容易在不同场景中使用函数。了解如何在 TypeScript 中定义和使用可选参数可以极大地改善您的开发体验,从而产生更易于维护和表达的代码。

更新于: 2023-08-21

225 次查看

开启您的 职业生涯

通过完成课程获得认证

开始学习
广告