- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章详解 TypeScript 函数声明和重载由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
在 JavaScript 中,函数是构建应用的一块基石,我们可以使用函数抽离可复用的逻辑、抽象模型、封装过程。在TypeScript中,函数仍然是最基本、最重要的概念之一。下面就来看看TypeScript中的函数类型是如何定义和使用的.
函数类型的定义包括对参数和返回值的类型定义:
这里用function字面量和箭头函数两种形式定义了add函数。函数参数 arg1 和 arg2 都是数值类型,最后通过相加得到的结果也是数值类型.
如果在这里省略参数的类型,TypeScript 会默认这个参数是 any 类型;如果省略返回值的类型,如果函数无返回值,那么 TypeScript 会默认函数返回值是 void 类型;如果函数有返回值,那么 TypeScript 会根据定义的逻辑推断出返回类型.
需要注意,在TypeScript中,如果函数没有返回值,并且我们显式的定义了这个函数的返回值类型为 undefined,那就会报错:A function whose declared type is neither 'void' nor 'any' must return a value。正确的做法就是上面说的,将函数的返回值类型声明为void:
一个函数的定义包括函数名、参数、逻辑和返回值。为函数定义类型时,完整的定义应该包括参数类型和返回值类型。上面都是在定义函数的指定参数类型和返回值类型。下面来定义一个完整的函数类型,以及用这个函数类型来规定一个函数定义时参数和返回值需要符合的类型.
这里定义了一个变量 add,给它指定了函数类型,也就是(x: number, y: number) => number,这个函数类型包含参数和返回值的类型。然后给 add 赋了一个实际的函数,这个函数参数类型和返回类型都和函数类型中定义的一致,所以可以赋值。后面又给它赋了一个新函数,而这个函数的参数类型和返回值类型都是 string 类型,这时就会报如下错误:
注意: 函数中如果使用了函数体之外定义的变量,这个变量的类型是不体现在函数类型定义的.
使用接口可以清晰地定义函数类型。下面来使用接口为add函数定义函数类型:
通过接口形式定义了函数类型,这个接口Add定义了这个结构是一个函数,两个参数类型都是number类型,返回值也是number类型。当指定变量add类型为Add时,再要给add赋值,就必须是一个函数,且参数类型和返回值类型都要满足接口Add,显然这个函数并不满足条件,所以报错了.
可以使用类型别名来定义函数类型,这种形式更加直观易读:
使用type关键字可以给任何定义的类型起一个别名。上面定义了 Add 这个别名后,Add就成为了一个和(x: number, y: number) => number一致的类型定义。上面定义了Add类型,指定add类型为Add,但是给add赋的值并不满足Add类型要求,所以报错了.
注意,这里的=>与 ES6 中箭头函数的=>不同。TypeScript 函数类型中的=>用来表示函数的定义,其左侧是函数的参数类型,右侧是函数的返回值类型;而 ES6 中的=>是函数的实现.
TypeScript 会在编写代码时就检查出调用函数时参数中存在的一些错误:
在JavaScript中,上面代码中后面两个函数调用都不会报错, 只不过add(1, 2, 3)可以返回正确结果3,add(1)会返回NaN。而在TypeScript中我们设置了指定的参数,那么在使用该类型时,传入的参数必须与定义的参数类型和数量一致.
但有时候,函数有些参数不是必须的,我们就可以将函数的参数设置为可选参数。可选参数只需在参数名后跟随一个?即可:
上面的代码中,z是一个可选参数,那他的类型就是number | undefined,表示参数 z 就是可缺省的,那是不是意味着可缺省和类型是 undefined 等价呢?来看下面的例子:
可以看到,第三次函数调用报错了,这里的 ?: 表示在调用函数时可以不显式的传入参数。但是,如果声明了参数类型为 number | undefined,就表示函数参数是不可缺省且类型必须是 number 或者 undfined.
需要注意,可选参数必须放在必选参数后面,这和在 JS 中定义函数是一致的。来看例子:
在TypeScript中,可选参数必须放到最后,上面把可选参数x放到了必选参数y前面,所以报错了。在 JavaScript 中是没有可选参数这个概念的,只不过在编写逻辑时,可能会判断某个参数是否为undefined,如果是则说明调用该函数的时候没有传这个参数,要做下兼容处理;而如果几个参数中,前面的参数是可不传的,后面的参数是需要传的,就需要在该可不传的参数位置传入一个 undefined 占位才行.
在 ES6 标准出来之前,默认参数实现起来比较繁琐:
上面定义了一个计数器增值函数,这个函数有一个参数 step,即每次增加的步长,如果不传入参数,那么 step 接受到的就是 undefined,undefined 转换为布尔值是 false,所以 step || 1 这里取了 1,从而达到了不传参数默认 step === 1 的效果.
在 ES6 中,定义函数时给参数设默认值直接在参数后面使用等号连接默认值即可:
当为参数指定了默认参数时,TypeScript 会识别默认参数的类型;当调用函数时,如果给这个带默认值的参数传了别的类型的参数则会报错:
当然也可以显式地给默认参数 y 设置类型:
注意:函数的默认参数类型必须是参数类型的子类型,如下代码:
这里 add 函数参数 y 的类型为可选的联合类型 number | string,但是因为默认参数数字类型是联合类型 number | string 的子类型,所以 TypeScript 也会检查通过.
在 JavaScript 中,如果定义一个函数,这个函数可以输入任意个数的参数,那么就无法在定义参数列表的时候挨个定义。在 ES6 发布之前,需要用 arguments 来获取参数列表。arguments 是一个类数组对象,它包含在函数调用时传入函数的所有实际参数,它还包含一个 length 属性,表示参数个数。下面来模拟实现函数的重载:
这段代码如果在TypeScript环境中执行,三次handleData的调用都会报错,因为handleData函数定义的时候没有参数.
在 ES6 中,加入了…拓展运算符,它可以将一个函数或对象进行拆解。它还支持用在函数的参数列表中,用来处理任意数量的参数:
在 TypeScript 中可以为剩余参数指定类型:
在多数的函数中,是只能接受一组固定的参数。但是一些函数可以接收可变数量的参数、不同类型的参数,甚至可以根据调用函数的方式来返回不同类型的参数。要使用此类函数,TypeScript我们提供了函数重载功能。下面来看看函数重载是如何工作的.
先来看一个简单的例子:
这里的greet方法接收一个参数name,类型为string。那如果想让greet方法来接收一组名称怎么办?那这时greet函数会接收字符串或字符串数组作为参数,并返回字符串或字符串数组。那该如何改造这个函数?主要有两种方式:通过判断参数类型来修改函数签名 。
这是最简单直接的方式,但是在某些情况下,我们希望单独定义调用函数的方式,这时就可以使用函数重载.
当修改函数签名的方式比较复杂或者涉及到多种数据类型时,建议使用函数重载来完成。在函数重载中,我们需要定义重载签名和实现签名。重载函数签名只定义函数的参数和返回值类型,并不会定义函数的正文。对于一个函数不同的调用方式,就可以有多个重载签名.
下面来实现greet()函数的重载:
这里greet()函数有两个重载签名和一个实现签名。每个重载签名都描述了调用函数的一种方式。我们可以使用字符串参数或使用字符串参数数组来调用greet()函数.
现在就可以使用字符串或字符串数组的参数调用greet()):
在定义函数重载时,需要注意以下两点:
(1)函数签名是可以调用的 。
虽然上面我们定义了重载签名和签名方法,但是签名实现时不能直接调用的,只有重载签名可以调用:
这样调用的话就会报错:
也就是说,即使签名实现接收unknown类型的参数,但是我们不能直接给greet()方法来传递unknown类型的参数,参数只能是函数重载签名中定义的参数类型.
(2)实现签名必须是通用的 。
在实现签名时,定义的数据类型需要是通用的,以包含重载签名。假如我们把greet()方法的返回值类型定义为string,这时就会出问题了:
此时string[]类型就会和string不兼容。所以,实现签名的返回类型和参数类型都要包含所有重载签名中的参数类型和返回值类型,保证是通用的.
除了常规函数外,类中的方法也可以过载,比如用重载方法greet()来实现一个类:
Greeter类中包含了greet()重载方法:这里面有两个描述如何调用方法的重载签名,以及包含其实现签名。这样我们就可以通过两种方式调用hi.greet():
原文链接:https://mp.weixin.qq.com/s/dnPhSjRQIJrukBuC58S9CA 。
最后此篇关于详解 TypeScript 函数声明和重载的文章就讲到这里了,如果你想了解更多关于详解 TypeScript 函数声明和重载的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我已经写了并且 npm 发布了这个:https://github.com/justin-calleja/pkg-dependents 现在我正在用 Typescript 编写这个包:https://g
我有一个函数,我想在 TypeScript 中模拟它以进行测试。在我的测试中,我只关心 json和 status .但是,当使用 Jest 的 jest.spyOn 时我的模拟函数的类型设置为返回 h
我正在使用一个库 (Axios),它的包中包含 Typescript 声明。 我想声明一个将 AxiosResponse(在库的 .d.ts 文件中声明)作为参数的函数。我有以下内容: functio
我是 Typescript 的新手。我想使用 将一个 Typescript 文件加载到另一个 Typescript 文件中标签。 我做了一些事情,但它不起作用!请帮助我。 first.ts: imp
为什么我会收到下面屏幕截图中显示的错误? Atom 说我的 tsconfig.json“项目文件包含无效选项”用于 allowJs、buildOnSave 和 compileOnSave。 但是应该允
所以我正在创建一个 TypeScript 库,我可以轻松地将所有生成的 JS 文件编译成一个文件。有没有办法将所有 .ts 和 .d.ts 编译成一个 .ts 文件? 除了支持 JS 的版本(较少的智
Microsoft Research 提供了一种名为Safer TypeScript 的新 TypeScript 编译器变体: http://research.microsoft.com/en-us/
我需要这个来在单个文件中分发 TypeScript 中的库。有没有办法将多个 typescript 文件合并到(一个js文件+一个 typescript 定义)文件中? 最佳答案 要创建一个库,您可以
用例:我想知道一个函数在 typescript 中执行需要多少时间。我想为此目的使用装饰器。我希望装饰器应该返回时间以便(我可以进一步使用它),而不仅仅是打印它。 例如: export functio
我想检查一个类型是否可以为 null,以及它是否具有值的条件类型。 我尝试实现 type IsNullable = T extends null ? true : false; 但是好像不行 type
我的问题是基于这个 question and answer 假设我们有下一个代码: const myFn = (p: { a: (n: number) => T, b: (o: T) => v
我知道双重否定前缀,我知道 TypeScript 的单后缀(非空断言)。 但是这个双后缀感叹号是什么? /.*验证码为(\d{6}).*/.exec(email.body!!)!![1] 取自here
我正在使用以下文件结构在 Webstorm 中开发一个项目 | src | ... | many files | types | SomeInterface |
在 TypeScript 类中,可以为属性声明类型,例如: class className { property: string; }; 如何在对象字面量中声明属性的类型? 我试过下面的代码,但它
我正在寻找一种在不丢失推断类型信息的情况下将 TypeScript 中的文字值限制为特定类型的好方法。 让我们考虑一个类型Named,它保证有一个名字。 type Named = { name:
在 TypeScript 中,我想创建一个联合类型来表示属于一个或多个不同类型的值,类似于 oneOf在 OpenAPI或 JSON Schema .根据a previous answer on a
type Func = (foo:string) => void // function expression const myFunctionExpression:Func = function(f
假设我有一个联合类型,我正在使用类似 reducer 的 API 调用模式,看起来像这样: type Action = { request: { action: "create
我在 typescript 中有以下去抖功能: export function debounce( callback: (...args: any[]) => void, wait: numb
在 Vue3 的 defineComponent 函数中,第一个泛型参数是 Props,所以我在这里使用 Typescript 接口(interface)提供我的 props 类型。喜欢: expor
我是一名优秀的程序员,十分优秀!