热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

TypeScript基础之函数重载

TypeScript基础之函数重载-函数和JavaScript一样,TypeScript函数可以创建有名字的函数和匿名函数。具名函数functionadd(x,y){retur

函数

和Javascript一样,TypeScript函数可以创建有名字的函数和匿名函数。

// 具名函数
function add (x, y) {
    return x + y;
}

// 匿名函数
let myAdd = function (x, y) { return x + y; }
// 表达式中的 具名函数 在Javascript中存在这样一个限制,表达式中的 具名函数只识别为匿名函数 ,而忽略它的函数名
let fn = function add (x, y) { return x + y; }

为函数定义类型

function add (x: number, y: number): number {
    return x + y;
}

let myAdd = function(x: number, y: number): number { return x + y; };

注:给每个参数添加类型之后,可以不用给函数本身添加返回值类型,因为TypeScript能根据返回语句自动推断出返回值类型

函数重载

由于 Javascript 是一个动态语言,我们通常会使用不同类型的参数来调用同一个函数,该函数会根据不同的参数而返回不同的类型的调用结果:

function add (x, y) {
    return x + y;
}

add(1, 2);   // 3
add("1", "2");  // "12"

以上代码在JS环境中运行是没有问题的,但是如果在TypeScript环境下且TypeScript编译器开启noImplicitAny(将TypeScript从可选类型语言转换为强制类型检验语言)配置项时,以上代码会提示以下错误信息:

Parameter 'x' implicitly has an 'any' type.
Parameter 'y' implicitly has an 'any' type.


该信息告诉我们参数 x 和参数 y 隐式具有 any 类型。为了解决这个问题,我们可以为参数设置一个类型。因为我们希望 add 函数同时支持 string 和 number 类型,因此我们可以定义一个 string | number 联合类型

function add (x: number | string, y: number | string) {
    if (typeof x === 'string' || typeof y === 'string') {
        return x.toString() + y.toString();
    }
    return x + y;
}

设置了联合类型后,之前错误提示信息就消失了,接着下一步:

let result = add('hearts', 'spades');
result.split(' ');

我们想当然的以为result类型为string,然后就可以正常使用字符串对象上的split方法, 结果又出现了新问题, 提示number类型的对象上并不存在split属性。

Property 'split' does not exist on type 'string | number'.  
Property 'split' does not exist on type 'number'.

那怎么处理呢?
这时可以使用函数重载。可以为同一个函数提供多个函数类型定义来进行函数重载(函数名称相同,参数数量或类型不同, 或者参数数量相同同时参数顺序不同)。

如何进行定义?
定义函数重载需要定义重载签名和一个实现签名。
其中重载签名定义函数的形参和返回类型,没有函数体。
一个函数可以有多个重载签名:主要是可以精确显示函数的输入输出,对应于调用该函数的不同方式。
此外, 实现签名还具有参数类型和返回类型,而且还有实现函数的主体,且只能有一个实现签名。
实现签名主要是将所有的输入输出类型做一个全量定义,防止TS编译报错,实现签名就是整个整个函数实现的全部逻辑 。
如:

type Types = number | string;
// 重载签名
function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: string, y: number): string;
function add(x: number, y: string): string;
function add(x: Types, y: Types) {
    if (typeof x === 'string' || typeof y === 'string') {
        return x.toString() + y.toString();
    }
    return x + y;
}
const result = add('hearts', ' spades');
result.split(' ');

编译成功,编译结果如下:

以上定义了4个重载签名和一个实现签名。
需要注意的是: 当 TypeScript 编译器处理函数重载时,它会查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。

其他:
从编译后结果可以看出Javascript 作为动态语言, 是没有函数重载这一说法的。原因如下:

  • 参数没有类型的区分;
  • 对参数个数也没有检查

既然语言层面无法自动进行重载,但借助其动态的特性,我们可以在代码中手动检查入参的类型,或者通过 arguments 获取到参数个数,从而实现根据不同的入参做不同的操作。

参考资料

https://www.tslang.cn/docs/ha...
https://cloud.tencent.com/dev...
https://cloud.tencent.com/dev...


推荐阅读
  • TS-入门学习笔记TypeScript是JavaScript的一个超集,主要提供了类型系统和对ES6的支持。与js相比,最大的有点是类型系统的引入,由于js本身是弱类型语言,所以天 ... [详细]
  • 前言小伙伴们大家好。从今天开始我们将从 ... [详细]
  • 深入理解TypeScript认识TypeScript&配置详解
    为什么使用TypeScript?最初使用TypeScript开发项目的时候,觉得很繁琐,定义每一个变量还要加上类型,尤其是对象形式的,几乎每一个用到的都要定一个接口,还要为每一 ... [详细]
  • 小编给大家分享一下TypeScript2.7有什么改进,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收 ... [详细]
  • 枚举使用枚举我们可以定义一些带名字的常量。使用枚举可以清晰地表达意图或创建一组有区别的用例。TypeScript支持数字的和基于字符串的枚举。数字枚举首先我们看看数字枚举,如果你使 ... [详细]
  • 我试图在Angular2应用程序中使用元素调整大小检测器库(https:github.comwnrelement-resize-detector).根据我有限的JS模块知识,该库似 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
author-avatar
洋芋片
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有