iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何解析TypeScript中函数重载写法
  • 805
分享到

如何解析TypeScript中函数重载写法

2023-06-25 22:06:28 805人浏览 独家记忆
摘要

今天就跟大家聊聊有关如何解析typescript中函数重载写法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。前言:大多数函数接受一组固定的参数。但有些函数可以接受可变数量的参数,不同

今天就跟大家聊聊有关如何解析typescript中函数重载写法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

    前言:

    大多数函数接受一组固定的参数。但有些函数可以接受可变数量的参数,不同类型的参数,甚至可以根据你调用函数的方式返回不同的类型。为了注释这样的函数,TypeScript 提供了函数重载功能。

    1. 函数签名

    我们先来考虑一个函数,它返回给一个特定的人的问候信息。

    function greet(person: string): string {  return `Hello, ${person}!`;}

    上面的函数接受1个字符类型的参数:人的名字。调用该函数是非常简单的:

    greet('World'); // 'Hello, World!'

    如果你想让 greet()函数更加灵活,怎么办?例如,让它另外接受一个要问候的人的列表。

    这样的函数将接受一个字符串或字符串数组作为参数,并返回一个字符串或字符串数组。

    如何对这样的函数进行注释?有2种方法。

    第一种方法很简单,就是通过更新参数和返回类型直接修改函数签名。

    下面重构后greet()的样子:

    function greet(person: string | string[]): string | string[] {  if (typeof person === 'string') {    return `Hello, ${person}!`;  } else if (Array.isArray(person)) {    return person.map(name => `Hello, ${name}!`);  }  throw new Error('Unable to greet');}

    现在我们可以用两种方式调用 greet():

    greet('World');          // 'Hello, World!'greet(['小智', '大冶']); // ['Hello, 小智!', 'Hello, 大冶!']

    直接更新函数签名以支持多种调用方式是一种常见的好方法。

    然而,在某些情况下,我们可能需要采用另一种方法,分别定义你的函数可以被调用的所有方式。这种方法被称为函数重载。

    2.函数重载

    第二种方法是使用函数重载功能。当函数签名相对复杂且涉及多种类型时,我推荐使用这种方法。

    定义函数重载需要定义重载签名和一个实现签名。

    重载签名定义函数的形参和返回类型,没有函数体。一个函数可以有多个重载签名:对应于调用该函数的不同方式。

    另一方面,实现签名还具有参数类型和返回类型,而且还有实现函数的主体,且只能有一个实现签名。

    // 重载签名function greet(person: string): string;function greet(persons: string[]): string[]; // 实现签名function greet(person: unknown): unknown {  if (typeof person === 'string') {    return `Hello, ${person}!`;  } else if (Array.isArray(person)) {    return person.map(name => `Hello, ${name}!`);  }  throw new Error('Unable to greet');}

    greet() 函数有两个重载签名和一个实现签名。

    每个重载签名都描述了可以调用该函数的一种方式。就 greet()函数而言,我们可以用两种方式调用它:用一个字符串参数,或用一个字符串数组参数。

    实现签名 function greet(person: unknown): unknown { ... } 包含了该函数如何工作的适当逻辑。

    现在,和上面一样,可以用字符串或字符串数组类型的参数来调用 greet()

    greet('World');          // 'Hello, World!'greet(['小智', '大冶']); // ['Hello, 小智!', 'Hello, 大冶!']

    2.1 重载签名是可调用的

    虽然实现签名实现了函数行为,但是它不能直接调用。只有重载签名是可调用的。

    greet('World');          // 重载签名可调用greet(['小智', '大冶']); // 重载签名可调用const someValue: unknown = 'Unknown';greet(someValue);       // Implementation signature NOT callable// 报错No overload matches this call.  Overload 1 of 2, '(person: string): string', gave the following error.    Argument of type 'unknown' is not assignable to parameter of type 'string'.  Overload 2 of 2, '(persons: string[]): string[]', gave the following error.    Argument of type 'unknown' is not assignable to parameter of type 'string[]'.

    在上面的示例中,即使实现签名接受unknown参数,也不能使用类型为 unknown (greet(someValue)) 的参数调用 greet() 函数。

    2.1 实现签名必须是通用的

    // 重载签名function greet(person: string): string;function greet(persons: string[]): string[]; // 此重载签名与其实现签名不兼容。 // 实现签名function greet(person: unknown): string {  // ...  throw new Error('Unable to greet');}

    重载签名函数 greet(person: string[]): string[] 被标记为与greet(person: unknown): string不兼容。

    实现签名的 string 返回类型不够通用,不能与重载签名的 string[] 返回类型兼容。

    3.方法重载

    虽然在前面的例子中,函数重载被应用于一个普通函数。但是我们也可以重载一个方法

    在方法重载区间,重载签名和实现签名都是类的一部分了。

    例如,我们实现一个 Greeter类,有一个重载方法greet()

    class Greeter {  message: string;   constructor(message: string) {    this.message = message;  }   // 重载签名  greet(person: string): string;  greet(persons: string[]): string[];   // 实现签名  greet(person: unknown): unknown {    if (typeof person === 'string') {      return `${this.message}, ${person}!`;    } else if (Array.isArray(person)) {      return person.map(name => `${this.message}, ${name}!`);    }    throw new Error('Unable to greet');  }

    Greeter 类包含 greet() 重载方法: 2个重载签名描述如何调用该方法,以及包含正确实现的实现签名

    由于方法重载,我们可以用两种方式调用 hi.greet():使用一个字符串或使用一个字符串数组作为参数。

    const hi = new Greeter('Hi'); hi.greet('小智');       // 'Hi, 小智!'hi.greet(['王大冶', '大冶']); // ['Hi, 王大冶!', 'Hi, 大冶!']

    4. 何时使用函数重载

    函数重载,如果使用得当,可以大大增加可能以多种方式调用的函数的可用性。这在自动补全时特别有用:我们会在自动补全中列出所有可能的重载记录。

    然而,在某些情况下,建议不要使用函数重载,而应该使用函数签名。

    例如,不要对可选参数使用函数重载:

    // 不推荐做法function myFunc(): string;function myFunc(param1: string): string;function myFunc(param1: string, param2: string): string;function myFunc(...args: string[]): string {  // implementation...}

    在函数签名中使用可选参数是足够的:

    // 推荐做法function myFunc(param1?: string, param2: string): string {  // implementation...}

    5.总结

    TypeScript中的函数重载让我们定义以多种方式调用的函数。

    使用函数重载需要定义重载签名:一组带有参数和返回类型的函数,但没有主体。这些签名表明应该如何调用该函数。

    看完上述内容,你们对如何解析TypeScript中函数重载写法有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网精选频道,感谢大家的支持。

    --结束END--

    本文标题: 如何解析TypeScript中函数重载写法

    本文链接: https://www.lsjlt.com/news/306315.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • C++ 生态系统中流行库和框架的贡献指南
      作为 c++++ 开发人员,通过遵循以下步骤即可为流行库和框架做出贡献:选择一个项目并熟悉其代码库。在 issue 跟踪器中寻找适合初学者的问题。创建一个新分支,实现修复并添加测试。提交...
      99+
      2024-05-15
      框架 c++ 流行库 git
    • C++ 生态系统中流行库和框架的社区支持情况
      c++++生态系统中流行库和框架的社区支持情况:boost:活跃的社区提供广泛的文档、教程和讨论区,确保持续的维护和更新。qt:庞大的社区提供丰富的文档、示例和论坛,积极参与开发和维护。...
      99+
      2024-05-15
      生态系统 社区支持 c++ overflow 标准库
    • c++中if elseif使用规则
      c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
      99+
      2024-05-15
      c++
    • c++中的继承怎么写
      继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
      99+
      2024-05-15
      c++
    • c++中如何使用类和对象掌握目标
      在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
      99+
      2024-05-15
      c++
    • c++中优先级是什么意思
      c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
      99+
      2024-05-15
      c++
    • c++中a+是什么意思
      c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
      99+
      2024-05-15
      c++
    • c++中a.b什么意思
      c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
      99+
      2024-05-15
      c++
    • C++ 并发编程库的优缺点
      c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
      99+
      2024-05-15
      c++ 并发编程
    • 如何在 Golang 中备份数据库?
      在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
      99+
      2024-05-15
      golang 数据库备份 mysql git 标准库
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作