一文搞懂 TS中 函数、枚举、别名 | TypeScript 入门指南 06
大家好,我是王天~
这篇文章是 ts入门指南系列中第6 篇,主要讲解ts中的 函数、枚举、别名应用~ 如有不对的地方 欢迎留言反馈哈
函数
在TypeScript中,可选参数和默认参数、剩余参数以及函数重载可以帮助我们更灵活地定义和使用函数。
1、可选参数和默认参数:
可选参数允许我们在调用函数时省略一些参数,而默认参数为函数的参数提供了默认值。
举个例子,假设我们有一个函数greet用于问候,接受一个名称参数和一个可选的消息参数:
function greet(name: string, message?: string) {if (message) {console.log(`Hello, ${name}! ${message}`);} else {console.log(`Hello, ${name}!`);}
}
当我们调用这个函数时,可以只传递名称参数,而可选的消息参数可以省略:
greet("Alice"); // 输出:Hello, Alice!
如果我们想要提供消息参数,可以在调用时传递它:
greet("Bob", "How are you?"); // 输出:Hello, Bob! How are you?
此时,函数内部会打印带有消息的完整问候语。可选参数和默认参数可以使函数使用更加方便和灵活。
2、剩余参数:
剩余参数允许我们在函数中接受不定数量的参数,并将它们作为数组在函数内部使用。
举个例子,我们有一个函数sum用于计算一组数字的总和:
function sum(...numbers: number[]) {let total = 0;for (let number of numbers) {total += number;}return total;
}
我们可以传递任意数量的参数给函数,并且函数内部会将这些参数相加并返回结果:
console.log(sum(1, 2, 3)); // 输出:6
console.log(sum(4, 5, 6, 7, 8)); // 输出:30
剩余参数使用三个点(...)前缀来表示,它将多个参数收集到一个数组中,方便在函数内部进行处理。这样,我们可以更便捷地传递和处理不定数量的参数。
3、重载:
我们在js中总是不经意间使用函数重载,根据不同的参数类型或个数来执行不同的逻辑,这就是函数重载。
它在类型检查和类型推断方面提供了更强大的功能。
下面例子,展示了如何使用函数重载来实现一个根据参数的不同选择执行不同逻辑的函数:
function formatData(data: string): string;
function formatData(data: number): number;
function formatData(data: string | number): string | number {if (typeof data === 'string') {return data.toUpperCase();} else if (typeof data === 'number') {return data.toFixed(2);}
}const result1 = formatData('hello'); // 返回类型为 string,结果为 "HELLO"
const result2 = formatData(3.14159); // 返回类型为 number,结果为 3.14
上述例子中,我们定义了一个名为 formatData 的函数,它接受一个参数 data,可以是字符串或数字类型。通过函数重载,我们提供了两个函数类型定义:第一个重载接受字符串参数并返回字符串,第二个重载接受数字参数并返回数字。在函数体实现中,根据不同的参数类型执行不同的逻辑操作。
通过使用函数重载,我们可以在类型安全的环境中,根据参数类型提供不同的实现,提高代码的可靠性和可读性。这对于需要根据参数进行不同处理的场景非常有用,比如解析不同类型的输入数据、根据参数类型进行计算等等
枚举
1. 简介
在 TypeScript 中,枚举(Enum)是一种定义常量的方式,可以用简洁、可读性强的方式,定义一组命固定集合的值(常量)。
在 JavaScript 中,在没有枚举语言特性的情况下,常常使用以下方法来表示一组常量:
-
使用命名的变量或常量。
const RED = "red";
const GREEN = "green";
const BLUE = "blue";
这种方式可能容易出错,因为限制了变量的作用域,而且可能会有命名冲突或拼写错误等问题。
-
使用简单的对象字面量。
const Colors = {RED: "red",GREEN: "green",BLUE: "blue"
};
使用对象字面量可以提供一些命名空间的支持,但并不能限制变量值的修改,这意味着你仍然可以通过赋值操作改变枚举值。
这就是 TypeScript 中枚举的作用所在:它提供了一种更强大、更安全的方式来定义一组有限的常量。
枚举在 TypeScript 中的优势和解决了 JavaScript 中的一些痛点包括:
-
类型安全性:枚举在 TypeScript 中是具有类型的,编译器可以在编译时进行类型检查,确保只使用枚举中定义的值。
-
命名空间和作用域:枚举在一定程度上提供了命名空间的支持,可以更好地组织和管理常量集合,并且不会发生命名冲突。
-
可读性:通过使用枚举,可以直观地了解代码中某个值的含义,提高了代码的可读性和可维护性。
-
自文档化:枚举可以作为文档的一部分,提供了一个可供其他开发人员查阅的可扩展的集合。
总之,TypeScript 中的枚举提供了一种更加结构化和类型安全的方式,来表示固定集合的值,并解决了 JavaScript 中使用常量时的一些问题。
2. 基本用法
枚举的基本用法是定义一个枚举类型,然后使用它来声明变量或函数参数。下面是一个基本的示例:
// 定义一个表示颜色的枚举
enum Color {Red,Green,Blue
}// 使用枚举类型声明变量
let myColor: Color = Color.Green;
console.log(myColor); // 输出: 1
在这个例子中,我们定义了一个枚举类型 Color,它包含了三个成员:Red、Green 和 Blue。
默认情况下,枚举成员的值从 0 开始自动递增,所以 Red 的值是 0,Green 的值是 1,Blue 的值是 2。
我们可以使用枚举类型来声明变量 myColor,并将它的值设置为 Color.Green。最后,我们打印了 myColor 的值,结果是 1。
3. 常数项和计算所得项
在枚举中,成员可以是常数项或计算所得项。
常数项是声明枚举时就已经指定好的值,这些值不能被修改。如果没有给常数项赋值,它们将按照从 0 开始的顺序递增。
计算所得项是根据表达式在运行时计算出的值,可以用于根据之前定义的常数项进行计算。计算所得项必须在表达式中使用,不能直接赋值给其他成员。
以下是一个示例,演示了常数项和计算所得项的用法:
enum Direction {Up, // 常数项,默认值为 0Down, // 常数项,默认值为 1Left = 10, // 常数项指定具体值为 10Right = Left + 1 // 计算所得项,值为 11(Left 的值加 1)
}console.log(Direction.Up); // 输出: 0
console.log(Direction.Left); // 输出: 10
console.log(Direction.Right); // 输出: 11
这个例子中,Direction 枚举包含了四个成员。
Up 和 Down 是常数项,默认情况下它们的值分别是 0 和 1。Left 是一个常数项,我们明确地将它的值设置为 10。Right 是一个计算所得项,它的值是 Left + 1,即 10 + 1,结果是 11。
4. 常数枚举
常数枚举是一种特殊类型的枚举,在编译时会被删除,并且对枚举成员的引用会被替换为具体的值。常数枚举可以在一些性能优化和减少代码量的情况下使用。
下面是一个示例,展示了常数枚举的用法:
const enum Size {Small,Medium,Large
}function printSize(size: Size): void {console.log(size);
}printSize(Size.Small); // 编译后会直接替换为具体的值
在这个例子中,我们使用 const enum 关键字定义了一个常数枚举 Size,它包含三个成员。
printSize 函数接受一个参数 size,类型为 Size 枚举。在函数体内,我们打印了 size 的值。由于 Size 是一个常数枚举,在编译时会被直接替换为具体的值。
所以,当我们调用 printSize(Size.Small) 时,编译后的代码将直接打印 0。
5. 实战开发案例
让我们以一个实战开发案例来综合应用学到的 TypeScript 枚举知识。
假设你正在开发一个游戏,游戏中有不同种类的角色,每个角色都有不同的属性。我们可以使用枚举来表示不同种类的角色以及它们的属性。
以下是一个示例代码:
enum MonsterType {Goblin,Orc,Troll
}interface Monster {type: MonsterType;name: string;health: number;attack: number;
}function createMonster(monsterType: MonsterType, name: string): Monster {let monster: Monster;switch (monsterType) {case MonsterType.Goblin:monster = { type: monsterType, name, health: 10, attack: 5 };break;case MonsterType.Orc:monster = { type: monsterType, name, health: 20, attack: 10 };break;case MonsterType.Troll:monster = { type: monsterType, name, health: 30, attack: 15 };break;default:throw new Error("未知的角色类型");}return monster;
}const goblin = createMonster(MonsterType.Goblin, "格鲁皮");
console.log(goblin);
在这个案例中,我们定义了一个枚举类型 MonsterType 来表示不同种类的角色。
别名
在 TypeScript 中,type 关键字用于创建类型别名(Type Aliases)。类型别名允许你为一个具体的类型或类型组合定义一个名称,以便在代码中重复使用。
type 的作用有以下几个方面:
-
类型复用: 通过类型别名,你可以将一个复杂的类型定义为一个名称,然后在需要使用该类型的地方直接使用该名称。这有助于提高代码的可读性和可维护性。
type User = {name: string;age: number;
};type Callback = (data: User) => void;function fetchData(callback: Callback) {// ...
}
在上面的例子中,通过类型别名 User 和 Callback 分别定义了一个用户对象类型和一个回调函数类型,然后在 fetchData 函数中使用了这两个类型别名。
-
类型组合: 类型别名还可以用于组合现有的类型来创建新的类型。这可以通过交叉类型(Intersection Types)和联合类型(Union Types)来实现。
type Point = {x: number;y: number;
};type Color = 'red' | 'green' | 'blue';type ColoredPoint = Point & { color: Color };type Shape = Square | Circle;interface Square {kind: 'square';size: number;
}interface Circle {kind: 'circle';radius: number;
}
在上述代码中,ColoredPoint 类型通过交叉类型将 Point 类型和包含 color 属性的对象类型组合而成,Shape 类型通过联合类型将 Square 和 Circle 接口组合而成。
-
类型推导(Type Inference): 当你使用类型别名初始化变量时,TypeScript 可以推导变量的类型,并将其视为该类型别名所代表的类型。
type Point = {x: number;y: number;
};const origin: Point = { x: 0, y: 0 };
在上面的例子中,通过类型别名 Point 定义了一个坐标点类型,然后通过赋值给 origin 变量,TypeScript 推导出 origin 的类型为 Point。
类型别名的使用使得 TypeScript 中的类型定义更加灵活和可维护。通过使用类型别名,你可以更好地组织和管理代码中的复杂类型,提高代码的可读性和可维护性。
此外,类型别名还可以与其他 TypeScript 的高级类型特性(如泛型、条件类型等)结合使用,进一步增强类型系统的能力。
type vs interface
表示类型
类型别名(type)是一个定义别名的工具,可以将多个类型组合起来形成一个新类型。比如特定的对象结构,联合类型、函数类型等、可以表示非对象类型
可以应用于以下数据类型:
-
基本类型(如字符串、数字、布尔值等)
-
联合类型(Union Types)
-
交叉类型(Intersection Types)
-
元组(Tuple)
-
函数类型(Function Types)
-
对象类型(Object Types)
-
类型字面量(Type Literals)
-
类型别名的自身引用(Recursive Type Aliases)
接口(interface)主要用于定义对象的形状和结构,只能表示对象类型
-
对象类型(Object Types)
-
类类型(Class Types)
继承状态
-
type 不可继承
-
interface可以继承 class 、interface、type
如果喜欢或者 有所启发,欢迎 star,对作者也是一种鼓励。
相关文章:
一文搞懂 TS中 函数、枚举、别名 | TypeScript 入门指南 06
大家好,我是王天~ 这篇文章是 ts入门指南系列中第6 篇,主要讲解ts中的 函数、枚举、别名应用~ 如有不对的地方 欢迎留言反馈哈 函数 在TypeScript中,可选参数和默认参数、剩余参数以及函数重载可以帮助我们更灵活地定义和使用函数。 1、可…...
基于JAVA+SpringBoot+Vue的前后端分离的图书馆管理系统
基于JAVASpringBootVue的前后端分离的图书馆管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末附源码下载链接&#…...
基于SpringBoot+Vue的鲜花销售/鲜花商城/花店管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的鲜花销售…...
信号发生器在扫描模式下输出正弦波信号,需要注意设置哪些参数
在信号发生器工作于扫描模式(Sweep Mode)并输出正弦波信号的情况下,需对设备进行以下关键参数设置: 1、波形设置 选择波形:正弦波(Sine Wave) 正弦波是常见的周期性波形,在扫描模式…...
xss-labs-master通关教程
一.level1 先来进行一下代码审计 <?php ini_set("display_errors", 0);//关闭错误显示 $str $_GET["name"]; //接受URL来的get形式的name传参 echo "<h2 aligncenter>欢迎用户".$str."</h2>";//在网页输出&#x…...
断点回归模型
断点回归(Regression Discontinuity Design, RDD)是一种准实验设计方法,用于评估政策或其他干预措施的效果。这种方法利用了一个清晰的阈值或“断点”,在这个阈值上,处理状态(例如是否接受某种干预…...
app广告推送常见业务术语
DAU: 日活跃用户(Daily Active Users) GMV: 商品交易总额(Gross Merchandise Volume) DSP=demand side platform=需求方平台 DMP=data management platform数据管理平台 ADX=ad exchange=广告交…...
2024/9/11 小型PLC典型应用2:伺服canlink配置、指令、应用
下面这个指令需要设置伺服的急停方式(例如:惯性停机、急停等等) 通讯故障步骤排查 1:接线问题 2:配置问题(波特率.....)...
在IDEA中如何创建web项目?——不使用Archetype
二、不使用Archetype 1、创建Maven项目 (1)首先打开Project Structure:File——>Project Structure或者快捷键crtlaltshifts (2)Module——>New Module: (3)在新打开的页面下…...
基于C#+SQL Server2008 开发三层架构(CS界面)图书管理系统
图书管理系统 一、项目背景及意义 当今由于信息技术的飞速发展,图书馆作为社会知识信息媒介的功能日益重要,网络环境下的信息资源建设知识仓库的设计,开放存取学术交流模式,知识管理系统,智能检索,数字参…...
AIGC简化文件管理:Python自动重命名Word和PDF文件
1.背景 大家应该也有遇到,自己电脑有很多文件命名不合理的文件,比如:文件1、想法3 ,当你长时间再看到这个文件的时候,已经很难知道文件内容。 今天我们将借助AIGC的编码能力,帮我们生成一个批量改文件名的…...
产线工控安全之防勒索病毒杀手锏
在当今数字化时代,数据安全已成为企业运营中不可或缺的一部分。勒索病毒和内部泄密事件的频发,使得企业必须采取更为严格的安全措施来保护其关键数据和运营系统。苏州深信达网络科技推出的MCK主机加固解决方案,正是为了应对这些挑战而设计的。…...
超详细超实用!!!网站开发页面适配360浏览器兼容模式
云风网 云风笔记 云风知识库 开发网站偶尔会遇到需要兼容ie的需求,这里以360浏览器为例,360浏览器是基于Chrome和IE双核浏览器,在极速模式下是跟谷歌浏览器内核一致的,兼容模式下的内核是IE内核。这里尤其是360兼容模式下&#x…...
【Redis】主从复制 - 源码
因为主从复制的过程很复杂, 同时核心逻辑主要集中在 replication.c 这个文件中, 避免篇幅过大, 所以将主从复制中涉及这个文件的代码集中到了另一篇文章。 在当前文章主要分析主从复制的大体代码逻辑, 如果需要了解整体的过程, 可以配合 Redis 主从复制 - relication 源码分析 …...
Redis:缓存击穿
缓存击穿(热点key): 部分key(被高并发访问且缓存重建业务复杂的)失效,无数请求会直接到数据库,造成巨大压力 1.互斥锁:可以保证强一致性 线程一:未命中之后,获取互斥锁,再查询数据库重建缓存,写…...
一文说清什么是数据仓库
01 数据仓库的概念 数据仓库的概念可以追溯到20世纪80年代,当时IBM的研究人员开发出了“商业数据仓库”。本质上,数据仓库试图提供一种从操作型系统到决策支持环境的数据流架构模型。 目前对数据仓库(Data Warehouse)的标准定义&a…...
【算法】哈希表相关
【ps】本篇有 5 道 leetcode OJ。 一、算法简介 哈希表是一种存储数据的容器,可以快速查找某个元素,其查找的时间复杂度为 O(1),非常合适需要频繁查找某一个元素的场景。其具体用法为: 直接使用底层为哈希表的 STL 容器。用数组…...
企微机器人:企业数字化转型的得力助手
在数字化转型的浪潮中,企业对于提高运营效率、降低人力成本的需求日益迫切。企微机器人,作为基于企业微信平台开发的一种智能工具,以其高度自动化、灵活性强、安全性高和易于使用的特点,迅速成为企业内部的得力助手。本文将深入探…...
Linux编程之socket入门教程 socket通讯原理
在Linux网络编程中,套接字Socket是进程间通信的基础,用来在网络上不同主机间进行数据的发送和接收。套接字作为一种抽象的接口,它屏蔽了底层网络协议的复杂性,使得开发者可以专注于数据的传输。以下将详细介绍Linux网络编程中的So…...
Windows上安装RabbitMQ
rabbitmq是干嘛的我就不介绍了,直接开始安装教程。 搭建成功演示图 下载安装包 https://pan.baidu.com/s/1ZlCFxh9Q00ynSU3ZCpTC9Q?pwdry51pan.baidu.com/s/1ZlCFxh9Q00ynSU3ZCpTC9Q?pwdry51 下载完后有两个包(erlang和rabbitmq) 先安装otp_win64_24.1.7.exe…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
