9_TypeScript Array --[深入浅出 TypeScript 测试]

news2025/1/9 12:08:38

在 TypeScript 中,Array 是一种非常常用的数据结构,用来存储一系列相同或不同类型的元素。TypeScript 提供了对数组的强类型支持,使得你可以明确地指定数组中元素的类型,从而帮助你编写更安全和易于维护的代码。以下是关于 TypeScript 中 Array 的一些关键概念和用法:

数组声明

当然,下面是两个关于如何在 TypeScript 中声明数组的示例。每个示例展示了不同的方式来定义数组类型,并初始化它们。

示例 1: 使用泛型语法声明数组

在这个例子中,我们将使用 Array<T> 的泛型语法来声明一个只包含数字类型的数组。

// 声明一个数字类型的数组
let numbers: Array<number> = [1, 2, 3, 4, 5];

// 尝试添加一个非数字元素会引发编译时错误
// numbers.push("six"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'.

console.log(numbers); // 输出: [1, 2, 3, 4, 5]

示例 2: 使用方括号语法声明数组

这里我们使用更常见的方括号 T[] 语法来声明一个字符串类型的数组。

// 声明一个字符串类型的数组
let words: string[] = ["hello", "world", "TypeScript"];

// 向数组中添加新的字符串元素
words.push("is", "awesome");

console.log(words); // 输出: ["hello", "world", "TypeScript", "is", "awesome"]

// 尝试添加一个不同类型的元素也会引发编译时错误
// words.push(42); // Error: Argument of type 'number' is not assignable to parameter of type 'string'.

注意事项

  • 在上述两个示例中,如果你尝试向数组中添加与声明类型不符的元素(例如,在 numbers 数组中添加字符串或在 words 数组中添加数字),TypeScript 编译器会在编译阶段报错,防止潜在的运行时错误。
  • 这两种方法在功能上是等价的,选择哪种方式主要取决于个人或团队的编码风格偏好。大多数开发者倾向于使用方括号语法,因为它更加简洁。

通过这两种声明方式,你可以确保你的代码具有更好的类型安全性和可读性。

多类型数组

在 TypeScript 中,你可以创建包含多种类型元素的数组。这可以通过使用联合类型(Union Types)来实现。下面提供了两个关于如何声明和使用多类型数组的示例。

示例 1: 使用联合类型声明多类型数组

在这个例子中,我们将创建一个既可以存储数字也可以存储字符串的数组。

// 声明一个多类型数组,可以包含数字或字符串
let mixedArray: (number | string)[] = [1, "two", 3, "four"];

// 添加更多不同类型的元素
mixedArray.push(5);
mixedArray.push("six");

console.log(mixedArray); // 输出: [1, "two", 3, "four", 5, "six"]

// 尝试访问元素时需要进行类型检查以确保安全
for (const item of mixedArray) {
    if (typeof item === "number") {
        console.log(`Number: ${item}`);
    } else if (typeof item === "string") {
        console.log(`String: ${item}`);
    }
}

示例 2: 包含复杂类型的多类型数组

这个例子展示了如何创建一个包含更复杂类型的数组,例如对象和基本数据类型。这里我们定义了一个包含布尔值、字符串以及具有特定结构的对象的数组。

// 定义一个接口表示对象的结构
interface Person {
    name: string;
    age: number;
}

// 声明一个多类型数组,可以包含布尔值、字符串或符合 Person 接口的对象
let complexArray: (boolean | string | Person)[] = [
    true,
    "hello",
    { name: "Alice", age: 30 }
];

// 向数组中添加新元素
complexArray.push(false);
complexArray.push({ name: "Bob", age: 25 });

console.log(complexArray); // 输出: [true, "hello", {name: "Alice", age: 30}, false, {name: "Bob", age: 25}]

// 访问元素并处理不同类型的数据
for (const item of complexArray) {
    if (typeof item === "boolean") {
        console.log(`Boolean: ${item}`);
    } else if (typeof item === "string") {
        console.log(`String: ${item}`);
    } else {
        console.log(`Person: ${item.name}, Age: ${item.age}`);
    }
}

注意事项

  • 类型安全性:当从多类型数组中读取元素时,由于每个元素可能属于不同的类型,因此你通常需要使用 typeof 或者类型保护(Type Guards)来确定元素的具体类型,从而避免运行时错误。
  • 灵活性与约束:虽然多类型数组提供了更大的灵活性,但在某些情况下可能会降低代码的可预测性和类型安全性。因此,在设计时应该权衡是否真的需要多类型数组,或者是否可以通过其他方式(如对象或元组)更好地组织数据。

这两个示例展示了如何在 TypeScript 中有效地使用多类型数组,同时保持了良好的类型安全性和代码清晰度。

元组(Tuple)

元组(Tuple)是 TypeScript 中一种特殊类型的数组,它允许你定义固定长度和类型的数组。每个位置上的元素都有明确的类型,并且这些类型可以不同。下面提供了两个关于如何声明和使用元组的示例。

示例 1: 基本元组

在这个例子中,我们将创建一个包含字符串和数字的简单元组。

// 声明一个元组,第一个元素为字符串,第二个元素为数字
let nameAndAge: [string, number] = ["Alice", 30];

// 访问元组中的元素
console.log(`Name: ${nameAndAge[0]}, Age: ${nameAndAge[1]}`); // 输出: Name: Alice, Age: 30

// 尝试添加或修改超出定义长度的元素会引发编译时错误
// nameAndAge.push("extra"); // Error: Tuple type '[string, number]' of length '2' has no element at index '2'.
// nameAndAge[2] = "extra"; // Error: Index signature is only available on string or number literal types.

// 修改现有元素时也必须遵循定义的类型
nameAndAge[1] = 31; // 合法操作
// nameAndAge[0] = 42; // Error: Type 'number' is not assignable to type 'string'.

示例 2: 复杂元组

这个例子展示了如何创建一个更复杂的元组,其中包含不同类型的元素,包括对象、布尔值等。

// 定义一个接口表示对象的结构
interface Person {
    name: string;
    age: number;
}

// 声明一个复杂元组,包含字符串、Person 对象和布尔值
let record: [string, Person, boolean] = [
    "Employee",
    { name: "Bob", age: 25 },
    true
];

// 解构赋值以获取元组中的元素
const [title, person, active] = record;

console.log(`Title: ${title}, Name: ${person.name}, Age: ${person.age}, Active: ${active}`);
// 输出: Title: Employee, Name: Bob, Age: 25, Active: true

// 尝试修改元组中的元素时需要遵循定义的类型
record[2] = false; // 合法操作
// record[1] = "not a person"; // Error: Type 'string' is not assignable to type 'Person'.

// 添加新元素会导致编译错误
// record.push("extra"); // Error: Tuple type '[string, Person, boolean]' of length '3' has no element at index '3'.

注意事项

  • 固定长度:元组的长度是固定的,这意味着你不能向元组中添加额外的元素,也不能删除已有的元素。
  • 类型检查:当你访问或修改元组中的元素时,TypeScript 会确保你提供的值与该位置的预期类型匹配。
  • 解构赋值:你可以使用解构赋值来方便地从元组中提取多个值,这在处理返回多个值的函数时特别有用。
  • 扩展性:虽然元组的长度和类型是固定的,但在某些情况下,你可以通过联合类型或其他方式来增加一些灵活性。

这两个示例展示了如何在 TypeScript 中使用元组,同时保持了良好的类型安全性和代码清晰度。元组非常适合用于那些你需要确保特定顺序和类型的场景,例如函数参数列表、返回值或者配置项等。

数组方法

TypeScript 继承了 JavaScript 的所有数组方法,并且这些方法都是类型安全的。下面是一些常用的数组方法:

  • push(): 向数组末尾添加一个或多个元素,并返回新的长度。

    let arr = [1, 2, 3];
    arr.push(4); // arr 现在是 [1, 2, 3, 4]
    
  • pop(): 移除并返回数组最后一个元素。

    let last = arr.pop(); // last 是 4,arr 现在是 [1, 2, 3]
    
  • map(): 创建一个新数组,其结果是对原数组每个元素调用提供的函数后的值。

    let doubled = arr.map(x => x * 2); // doubled 是 [2, 4, 6]
    
  • filter(): 创建一个新数组,包含所有通过测试的元素。

    let filtered = arr.filter(x => x > 1); // filtered 是 [2, 3]
    
  • reduce(): 对数组中的每个元素执行一个由你提供的 reducer 函数(升序执行),将其结果汇总为单个值。

    let sum = arr.reduce((acc, curr) => acc + curr, 0); // sum 是 6
    
  • forEach(): 对数组的每个元素执行一次提供的函数。

    arr.forEach(x => console.log(x)); // 输出每一项
    
  • find(): 返回数组中满足提供的测试函数的第一个元素的值,如果未找到则返回 undefined

    let found = arr.find(x => x === 2); // found 是 2
    
  • some(): 检查数组中是否有至少一个元素满足提供的函数。

    let hasEven = arr.some(x => x % 2 === 0); // hasEven 是 true
    
  • every(): 检查数组中所有元素是否都满足提供的测试函数。

    let allPositive = arr.every(x => x > 0); // allPositive 是 true
    

数组解构

数组解构(Array Destructuring)是 TypeScript 和 JavaScript 中的一种语法特性,它允许你从数组中提取元素并直接赋值给变量。这种方式不仅可以简化代码,还能提高可读性。下面是两个关于如何使用数组解构的示例。

示例 1: 基本数组解构

在这个例子中,我们将展示如何从一个简单的数字数组中解构出前几个元素,并将它们赋值给单独的变量。

// 定义一个包含多个数字的数组
let numbers = [10, 20, 30, 40, 50];

// 使用解构赋值来获取数组中的前三个元素
let [first, second, third] = numbers;

console.log(`First number is ${first}`); // 输出: First number is 10
console.log(`Second number is ${second}`); // 输出: Second number is 20
console.log(`Third number is ${third}`); // 输出: Third number is 30

// 如果数组中的元素多于解构的数量,剩余的元素将被忽略
忽略某些元素

如果你只想解构部分元素,可以使用逗号来跳过不需要的元素:

// 只解构第一个和第三个元素,跳过第二个元素
let [first,, third] = numbers;

console.log(`First number is ${first}, Third number is ${third}`); // 输出: First number is 10, Third number is 30

示例 2: 解构时设置默认值和剩余元素

这个例子展示了更复杂的解构场景,包括为解构的变量设置默认值以及捕获剩余的所有元素。

// 定义一个包含字符串的数组
let words = ["hello", "world"];

// 使用解构赋值并设置默认值
let [greeting = "hi", target = "there", ...rest] = words;

console.log(`Greeting is ${greeting}, Target is ${target}`); // 输出: Greeting is hello, Target is world
console.log(`Remaining elements are:`, rest); // 输出: Remaining elements are: []

// 当数组长度小于解构变量数量时,默认值生效
words = ["goodbye"];
[greeting = "hi", target = "there", ...rest] = words;

console.log(`Greeting is ${greeting}, Target is ${target}`); // 输出: Greeting is goodbye, Target is there
console.log(`Remaining elements are:`, rest); // 输出: Remaining elements are: []
捕获剩余元素

使用 ... 语法可以捕获数组中所有未解构的剩余元素到一个新的数组中:

// 定义一个包含多个元素的数组
let items = ["apple", "banana", "cherry", "date", "elderberry"];

// 解构前两个元素,并捕获剩余的所有元素
let [firstItem, secondItem, ...remainingItems] = items;

console.log(`First item is ${firstItem}`); // 输出: First item is apple
console.log(`Second item is ${secondItem}`); // 输出: Second item is banana
console.log(`Remaining items are:`, remainingItems); // 输出: Remaining items are: ['cherry', 'date', 'elderberry']

类型推断

TypeScript 的类型推断(Type Inference)功能可以在你初始化变量时自动确定其类型,而无需显式地声明类型。这对于数组来说同样适用,当你初始化一个数组并赋予它一些初始值时,TypeScript 会根据这些值推断出数组的类型。下面是两个关于 TypeScript 数组类型推断的示例。

示例 1: 简单类型的数组类型推断

在这个例子中,我们将展示如何通过初始化一个只包含数字的数组来让 TypeScript 推断出这是一个 number[] 类型的数组。

// 初始化一个包含数字的数组
let numbers = [1, 2, 3, 4, 5];

// TypeScript 自动推断 numbers 的类型为 number[]
numbers.push(6); // 合法操作

// 尝试添加不同类型的元素会引发编译时错误
// numbers.push("seven"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'.

console.log(numbers); // 输出: [1, 2, 3, 4, 5, 6]

// 访问数组中的元素,类型安全
for (const num of numbers) {
    console.log(num * 2); // 输出每个数字乘以2的结果
}
解释:
  • 当我们用 [1, 2, 3, 4, 5] 初始化 numbers 变量时,TypeScript 根据提供的值自动推断出它的类型是 number[]
  • 如果尝试向数组中添加与推断类型不符的元素(例如字符串),TypeScript 编译器会在编译阶段报错,确保代码的类型安全性。

示例 2: 多类型数组的类型推断

这个例子展示了当数组包含多种类型的数据时,TypeScript 如何推断出联合类型的数组。

// 初始化一个多类型数组
let mixed = ["hello", 42, true, { key: "value" }];

// TypeScript 自动推断 mixed 的类型为 (string | number | boolean | { key: string })[]
mixed.push("world"); // 合法操作
mixed.push(84); // 合法操作
mixed.push(false); // 合法操作
mixed.push({ key: "another value" }); // 合法操作

// 尝试添加不匹配的类型会引发编译时错误
// mixed.push([1, 2, 3]); // Error: Argument of type 'number[]' is not assignable to parameter of type 'string | number | boolean | { key: string; }'.

console.log(mixed); // 输出: ["hello", 42, true, { key: "value" }, "world", 84, false, { key: "another value" }]

// 遍历数组时需要进行类型保护
for (const item of mixed) {
    if (typeof item === "string") {
        console.log(`String: ${item}`);
    } else if (typeof item === "number") {
        console.log(`Number: ${item}`);
    } else if (typeof item === "boolean") {
        console.log(`Boolean: ${item}`);
    } else {
        console.log(`Object with key: ${item.key}`);
    }
}
解释:
  • 在这里,mixed 数组包含了字符串、数字、布尔值和对象等多种类型的元素。TypeScript 根据这些值推断出数组的类型为 (string | number | boolean | { key: string })[]
  • 这种情况下,当你遍历或访问数组中的元素时,通常需要使用 typeof 或者自定义类型保护(Type Guards)来检查元素的具体类型,以确保操作的安全性。

总结

TypeScript 的数组功能强大且类型安全,提供了丰富的操作方式来处理集合数据。理解如何正确地声明和操作数组对于编写高效、可靠的 TypeScript 应用程序至关重要。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UVM: TLM机制

topic overview 不建议的方法&#xff1a;假如没有TLM TLM TLM 1.0 整个TLM机制下&#xff0c;底层逻辑离不开动作发起者和被动接受者这个底层的模型基础&#xff0c;但实际上&#xff0c;在验证环境中&#xff0c;任何一个组件&#xff0c;都有可能成为动作的发起者&#xff0…

Scratch023-(沙漠变绿洲)

提示&#xff1a; 知识回顾&#xff1a; 1、画笔的各个属性 2、“将笔的颜色设为”积木 3、“将笔的颜色增加”积木 文章目录 前言一、案例展示二、功能分析三、步骤拆解1.背景角色和画笔的初始化&#xff08;1&#xff09;初始化画笔2、一起绘制一个小雨滴3、绘制多个随机的小…

游戏语音趋势解析,社交互动有助于营造沉浸式体验

语音交互的新架构出现 2024 年标志着对话语音 AI 取得了突破&#xff0c;出现了结合 STT → LLM → TTS 模型来聆听、推理和回应对话的协同语音系统。 OpenAI 的 ChatGPT 语音模式将语音转语音技术变成了现实&#xff0c;引入了基于音频和文本信息进行端到端预训练的模型&…

详细全面讲解C++中重载、隐藏、覆盖的区别

文章目录 总结1、重载示例代码特点1. 模板函数和非模板函数重载2. 重载示例与调用规则示例代码调用规则解释3. 特殊情况与注意事项二义性问题 函数特化与重载的交互 2. 函数隐藏&#xff08;Function Hiding&#xff09;概念示例代码特点 3. 函数覆盖&#xff08;重写&#xff…

计算机网络之---物理层设备

什么是物理层设备 物理层设备是指负责数据在物理媒介上传输的硬件设备&#xff0c;它们主要处理数据的转换、信号的传输与接收&#xff0c;而不涉及数据的内容或意义。常见的物理层设备包括网卡、集线器、光纤收发器、调制解调器等。 物理层设备有哪些 1、网卡&#xff08;N…

js状态模式

允许一个对象在其内部状态改变时改变它的行为。 状态模式将对象的状态封装成独立的类&#xff0c;并使它们可以互相转换 // 定义状态接口class State {constructor() {if (this.constructor State) {throw new Error(不能实例化抽象类);}}// 定义状态方法handle(context) {th…

平面坐标转大地坐标(arcgisPro中进行)

1、将需要转换的红线导入arcgisPro中&#xff0c;如下&#xff1a; 2、在地图菜单栏中&#xff0c;选择坐标转换工具&#xff0c;如下&#xff1a; 3、打开坐标转换工具 4、开启捕捉 5、 设置大地坐标显示格式 6、如下&#xff1a; 7、显示如图&#xff1a; 8、再依次添加几个待…

(长期更新)《零基础入门 ArcGIS(ArcScene) 》实验七----城市三维建模与分析(超超超详细!!!)

城市三维建模与分析 三维城市模型已经成为一种非常普遍的地理空间数据资源,成为城市的必需品,对城市能化管理至关重要。语义信息丰富的三维城市模型可以有效实现不同领域数据与IS相信息的高层次集成及互操作,从而在城市规划、环境模拟、应急响应和辅助决策等众多领域公挥作用、…

SpringBootWeb 登录认证(day12)

登录功能 基本信息 请求参数 参数格式&#xff1a;application/json 请求数据样例&#xff1a; 响应数据 参数格式&#xff1a;application/json 响应数据样例&#xff1a; Slf4j RestController public class LoginController {Autowiredpriva…

夯实前端基础之HTML篇

知识点概览 HTML部分 1. DOM和BOM有什么区别&#xff1f; DOM&#xff08;Document Object Model&#xff09; 当网页被加载时&#xff0c;浏览器会创建页面的对象文档模型&#xff0c;HTML DOM 模型被结构化为对象树 用途&#xff1a; 主要用于网页内容的动态修改和交互&…

UI自动化测试保姆级教程--pytest详解(精简易懂)

欢迎来到啊妮莫的学习小屋 别让过去的悲伤&#xff0c;毁掉当下的快乐一《借东西的小人阿莉埃蒂》 简介 pytest是一个用于Python的测试框架, 支持简单的单元测试和复杂的功能测试. 和Python自带的UnitTest框架类似, 但是相比于UnitTest更加简洁, 效率更高. 特点 非常容易上手…

有序数据中插入不确定数据保证数据插入的位置顺序正确排序

解决有序数据中插入不确定数据保证数据插入的位置顺序正确排序 前言 java 数据库中存储自增id 有序的数据&#xff0c; 前端页面基于 id 5和 6 之间新增一条数据&#xff0c;在 id 6 和 7之间新增 2条&#xff0c;或者更复杂的场景&#xff0c;后台接口如何保存数据使得页面数…

基于 Apache Commons Pool 实现的 gRPC 连接池管理类 GrpcChannelPool 性能分析与优化

基于 Apache Commons Pool 实现的 gRPC 连接池管理类 GrpcChannelPool 性能分析与优化 1. 输出关键信息的代码示例 日志记录方法 使用以下代码记录连接池的关键信息&#xff0c;帮助分析连接池的状态和性能瓶颈&#xff1a; import org.apache.commons.pool2.impl.GenericO…

不同方式获取音频时长 - python 实现

DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” -------------------------------------------------------------…

在 C# 中显示动画 GIF 并在运行时更改它们

您可以通过将按钮、图片框、标签或其他控件的Image属性设置为 GIF 文件 来显示动画 GIF 。&#xff08;如果您在窗体的BackgroundImage属性中显示一个&#xff0c;则不会获得动画。&#xff09; 有几种方法可以在运行时更改 GIF。 首先&#xff0c;您可以将 GIF 添加为资源。…

Element-plus、Element-ui之Tree 树形控件回显Bug问题。

需求&#xff1a;提交时&#xff0c;需要把选中状态和半选中状态 的数据id提交。如图所示&#xff1a; 数据回显时&#xff0c;会出现代码如下&#xff1a; <template><el-tree ref"treeRef" :data"data" show-checkbox node-key"id" …

【江协STM32】9-1/2/3 USART串口协议、USART外设、串口发送串口发送+接收

1. 通信接口 通信的目的&#xff1a;将一个设备的数据传送到另一个设备&#xff0c;扩展硬件系统通信协议&#xff1a;制定通信的规则&#xff0c;通信双方按照协议规则进行数据收发全双工&#xff1a;指通信双方能够同时进行双向通信。发送线路和接收线路互不影响&#xff0c…

小程序租赁系统开发的优势与应用前景分析

内容概要 小程序租赁系统是一种新兴的数字化解决方案&#xff0c;旨在为用户提供更加便捷与高效的租赁服务。它通常包括一系列功能&#xff0c;如在线浏览、即时预定、支付功能以及用户反馈机制。这些系统在使用上极为友好&#xff0c;让用户能够轻松选择所需的商品或服务&…

25/1/8 算法笔记<强化学习> GYM环境

前几天花了好多时间在装各个仿真环境上&#xff0c;有V-rep,Pybullet,unity的Ml-agent,很多一大堆&#xff0c;好多好多问题差点逼疯我&#xff0c;可能就pybullet能玩一点&#xff0c;到之后学了机器人我再来玩它&#xff0c;最后的最后&#xff0c;我发现还得是我的gym&#…

学习随记:word2vec中归一化处理的作用

答案来自ai&#xff0c;直接复用为参考&#xff1a; 向量归一化的好处 将向量进行归一化&#xff0c;使其模长为 1&#xff08;即投射到单位圆/单位球上&#xff09;&#xff0c;在许多情况下具有实际意义和计算优势。以下是归一化的主要好处和原因&#xff1a; 1. 提高数值稳…