一文搞懂 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…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...

《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...