纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

TypeScript函数重载 TypeScript中函数重载写法

前端小智   2021-12-10 我要评论
想了解TypeScript中函数重载写法的相关内容吗前端小智在本文为您仔细讲解TypeScript函数重载的相关知识和一些Code实例欢迎阅读和指正我们先划重点:TypeScript函数重载写法,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中的函数重载让我们定义以多种方式调用的函数

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

此外你必须写出函数的正确实现(实现签名):参数和返回类型以及函数体**请注意实现签名是不可调用的**

除了常规的函数之外类中的方法也可以重载


相关文章

猜您喜欢

  • C语言浮点数转为字符串 C语言怎样把浮点数转换为字符串

    想了解C语言怎样把浮点数转换为字符串的相关内容吗码农有道在本文为您仔细讲解C语言浮点数转为字符串的相关知识和一些Code实例欢迎阅读和指正我们先划重点:C语言浮点数,C语言字符串,浮点数转字符串下面大家一起来学习吧..
  • Spring Boot JWT token自动续期 Spring Boot实现JWT token自动续期的实现

    想了解Spring Boot实现JWT token自动续期的实现的相关内容吗dreaming9420在本文为您仔细讲解Spring BootJWT token自动续期的相关知识和一些Code实例欢迎阅读和指正我们先划重点:SpringBootJWTtoken自动续期,SpringBoottoken自动续期下面大家一起来学习吧..

网友评论

Copyright 2020 www.eleasoftware.com 【绿软下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式