TypeScript - 函数(上)

目录

1、介绍 

2、函数类型表达式

3、呼叫签名

4、构造签名

5、泛型函数

6、推论

7、约束

8、使用约束值

9、指定类型参数


1、介绍 

函数是JavaScript应用程序的基础。 它帮助你实现抽象层,模拟类,信息隐藏和模块。 在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义 行为的地方。函数是任何应用程序的基本构建块,无论它们是本地函数、从其他模块导入的函数,还是类上的方法。 它们也是值,就像其他值一样,TypeScript 有很多方法来描述如何调用函数。 让我们学习如何编写描述函数的类型。

2、函数类型表达式

描述函数的最简单方法是使用函数类型表达式。 这些类型在语法上类似于箭头函数:

function Animal(fn: (age: number)=>void){return fn(20);
}function Cat(age: number) {console.log('age: ', age);
}// age:  20
Animal(Cat) 

语法(age: number) => void 表示“具有一个参数的函数,参数为数字类型,没有返回值”。 就像函数声明一样,如果未指定参数类型,则是隐式的 any 类型。

fn: (age: number)=>void 形成一个函数表达式,参数是必须的,需声明对应的类型,否则具有隐藏式的类型 any。

我们可以把函数类型表达式赋值给类型别名,如下所示:

type expFunc = (age: number) => void;function Animal(fn: expFunc) {return fn(20);
}function Cat(age: number) {console.log('age: ', age);
}// age:  20
Animal(Cat) 

3、呼叫签名

在 JavaScript 中,函数除了可调用之外,还可以具有属性。 但是,函数类型表达式语法不允许声明属性。 如果我们想描述一些可以用属性调用的东西,我们可以在对象类型中写一个调用签名

type DescInfo = {desc: string;(args: number): number
};function Animal(fn: DescInfo) {// 我是tom🐱今年2岁console.log(fn.desc + '今年' +fn(2) + '岁');
}function Cat(age: number) {return age;
}
Cat.desc = "我是tom🐱";Animal(Cat)

请注意,与函数类型表达式相比,语法略有不同 - 在参数列表和返回类型之间使用,而不是上面缩写的(fn: (age: number)=>void)这样。

4、构造签名

JavaScript 函数也可以与运算符一起调用。 TypeScript 将这些称为构造函数,因为它们通常会创建一个新对象。 您可以通过在呼叫签名前面添加关键字来编写构造签名new

type DescInfo = {new (args: number): Cat
};function Animal(fn: DescInfo) {return new fn(20);
}class Cat {age: number;constructor(age: number){this.age = age;}
}console.log(new Cat(20).age);  // 20

某些对象,如 JavaScript 的对象,可以带或不带 . 您可以任意组合同一类型的调用和构造签名:

interface Animal {new(name: string, birthday: Date);(n?:number): number; 
}

5、泛型函数

通常编写一个函数,其中输入的类型与输出的类型相关,或者两个输入的类型以某种方式相关。

function Animals(array: any[]) {return array[1];
}

如果函数返回数组元素的类型会更好,例如:any 或者其他类型

在 TypeScript 中,当我们想要描述两个值之间的对应关系时,会使用泛型。 我们通过在函数签名中声明一个类型参数来做到这一点:

function Animals<Type>(array: any[]) : Type | undefined {return array[1];
}

在函数定义是,指定泛型Type,在返回的时候也指定对应类型 Type | undefined,这样返回的结果就会事先定义的范围,这样也使得结果更可控。

function Animals<Type>(array: any[]) : Type | undefined {return array[1];
}
console.log(Animals([1,2])); // 2

6、推论

我们不必在此示例中指定。 类型是由 TypeScript 推断的 - 自动选择的。

我们也可以使用多个类型参数。 例如

function Animals<Input, Output>(arr: Input[], func: (arg: Input) => Output) : Output[] {return arr.map(func)
}
Animals([1,2,3], (n)=>console.log(n)); // 1 2 3

7、约束

我们编写了一些可以处理任何类型的值的通用函数。 有时我们想关联两个值,但只能对某个值子集进行操作。 在这种情况下,我们可以使用约束来限制类型参数可以接受的类型类型。

function longest<Type extends { length: number }>(a: Type, b: Type) {if (a.length >= b.length) {return a;} else {return b;}}const longerArray = longest([1, 2], [1, 2, 3]);const longerString = longest("alice", "bob");const notOK = longest(123, 100);// longest 指定类型必须有长度 ,字符串和数组都有长度,而数组没有length 

在此示例中,有一些有趣的事项需要注意。 我们允许 TypeScript 推断返回类型 。 返回类型推理也适用于泛型函数(longest)。

因为我们被限制为 ,所以我们被允许访问 和 参数的属性。 如果没有类型约束,我们将无法访问这些属性,因为这些值可能是没有 length 属性的其他类型的值。Type{ length: number }.length a b

和的类型是根据参数推断的。 请记住,泛型都是关于将两个或多个值与同一类型相关联!longerArraylongerString

8、使用约束值

function minimumLength<Type extends { length: number }>(obj: Type,minimum: number
): Type {if (obj.length >= minimum) {return obj;} else {return { length: minimum }; // 报错...}
}

发现else里面的return,报错了,如下所示: 

不能将类型“{ length: number; }”分配给类型“Type”。
"{ length: number; }" 可赋给 "Type" 类型的约束,但可以使用约束 "{ length: number; }" 的其他子类型实例化 "Type"。

如果返回是Type类型,可以调用函数试一下

const arr = minimumLength([1, 2, 3], 6);
console.log(arr.slice(0)); // [1, 2, 3]

如果把上面返回值改成obj,之后,上面代码是可以执行。

9、指定类型参数

TypeScript 通常可以在泛型调用中推断预期的类型参数,但并非总是如此。 例如,假设您编写了一个函数来组合两个数组:

function arrayConcat<Type>(arr1: Type[], arr2: Type[]): Type[] {return arr1.concat(arr2);
}

下面测试一下,传不同类型是否会报错提示:

console.log(arrayConcat([1,2,3], ['name']));  // 不能将类型“string”分配给类型“number”。
console.log(arrayConcat([1,2,3], [true]));    // 不能将类型“boolean”分配给类型“number”。
console.log(arrayConcat([1,2,3], [4, 5, 6]));    
console.log(arrayConcat([1,2,3], [undefined]));
console.log(arrayConcat([1,2,3], [null]));

根据以上测试结果,可以看出前2种会有对应错误提示。

如果能提前知道类型的参数,可以提前指定类型参数。如下所示:

console.log(arrayConcat<number | string>([1,2,3], ['name']));  
console.log(arrayConcat<number | boolean>([1,2,3], [true])); 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/3836.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css基础知识十二:CSS3常见动画有哪些?实现方式?

一、是什么 CSS动画&#xff08;CSS Animations&#xff09;是为层叠样式表建议的允许可扩展标记语言&#xff08;XML&#xff09;元素使用CSS的动画的模块 即指元素从一种样式逐渐过渡为另一种样式的过程 常见的动画效果有很多&#xff0c;如平移、旋转、缩放等等&#xff…

io.netty学习(十四)Netty 编码器

目录 前言 MessageToByteEncoder 抽象类 MessageToMessageEncoder 抽象类 总结 前言 上一篇我们讲解了解码器的相关知识&#xff0c;其中也提到了编码器的定义。 编码器就是用来把出站&#xff08;针对本身来讲&#xff0c;发送都是出站&#xff0c;接收都是入站&#xf…

开源 sysgrok — 用于分析、理解和优化系统的人工智能助手

作者&#xff1a;Sean Heelan 在这篇文章中&#xff0c;我将介绍 sysgrok&#xff0c;这是一个研究原型&#xff0c;我们正在研究大型语言模型 (LLM)&#xff08;例如 OpenAI 的 GPT 模型&#xff09;如何应用于性能优化、根本原因分析和系统工程领域的问题。 你可以在 GitHub …

「一本通 3.2 例 3」架设电话线

题目大意 在加权无向图上求出一条从 号结点到 号结点的路径&#xff0c;使路径上第 大的边权尽量小。 思路 由于是一次性的&#xff0c;且这题数据极小&#xff0c;考虑 正常情况下是来更新数组的&#xff0c;不过这次是更新 表示第个节点&#xff0c;&#xff08;可以…

ansible实训-Day2(ansible基本问题及部署安装)

一、前言 该篇是对ansible实训第二天内容的归纳总结&#xff0c;主要包括ansible的一些基本问题以及ansible的部署安装。 二、理论部分 Q1&#xff1a;什么是ansible Ansible是一种自动化IT工具&#xff0c;它可以帮助管理和自动化IT基础架构。使用Ansible&#xff0c;管理员…

并发List:CopyOnWriteArrayList

CopyOnWriteArrayList 适合写多读少 介绍 JUC包中的并发List只有CopyOnWriteArrayList。CopyOnWriteArrayList是一个线程安全的ArrayList&#xff0c;使用了写时复制策略&#xff0c;对其进行的修改操作都是在底层的一个复制的数组上进行的。 CopyOnWriteList 实现的接口和 Ar…

PACS医学影像系统(完整版)

一、PACS影像存取与传输系统以实现医学影像数字化存储、诊断为核心任务&#xff0c;从医学影像设备&#xff08;如CT、CR、DR、MR、DSA、RF等&#xff09;获取影像&#xff0c;集中存储、综合管理医学影像及病人相关信息&#xff0c;建立数字化工作流程。 二、系统可实现检查预…

python进行windows系统UI自动化之【pyautoit】

python进行windows系统UI自动化之【pyautoit】 一、AutoIT中文手册1.1、安装AutoIt1.2、使用Auto Window Info 二、python引用2.1、安装2.2、引用2.3、使用2.3.1、窗口操作2.3.2、控件操作2.3.3、进程操作2.3.4、鼠标操作2.3.5、键盘操作2.3.5.1、Send 是非常有用的一个函数/命…

C++ 程序设计入门

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

交换网络基础

交换网络基础 一、交换机的基础原理1.1、交换机1.2、小型交换网络1.3、交换机的转发行为1.4、交换机转发原理1.4.1、交换机初始状态1.4.2、学习MAC地址1.4.3、转发数据帧1.4.4、目标主机回复 1.5、基本配置1.6、总结 二、STP原理2.1、二层交换网络2.2、广播风暴&重复帧2.3、…

使用R绘制气泡图、带有显著性标记的热力图、渐变曲线图

大家好&#xff0c;我是带我去滑雪&#xff01; 一幅精美的科研绘图会有诸多益处&#xff0c;精美的图像可以更好地传达研究结果和数据分析的重要信息。通过使用清晰、直观和易于理解的图像&#xff0c;可以更好地向读者展示研究的发现&#xff0c;有助于读者理解和解释数据。还…

Chrome/Edge 浏览器多账号登录,测试同一业务系统的不同账号角色

文章目录 如何使用多账户&#xff1f;ChromeEdge 虽然说用不同浏览器测试也比较方便、还能顺带测试多浏览器兼容问题…… 但我是开发呀&#xff0c;我只想用我最习惯的谷歌浏览器完成快速开发&#xff0c;把功能铺上&#xff0c;专注于业务逻辑的开发 这些浏览器差异等只会给我…