TypeScript入门 (三)数据类型

head-bar

引言

大家好,我是GISer Liu😁,一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年9月学习赛的TypeScript学习总结文档。本文旨在全面介绍 TypeScript 中的各种数据类型,帮助读者深入理解每种数据类型的用法、内置属性和方法,以及在实际开发中的应用。💕💕😊


介绍

在 TypeScript 中,数据类型是构建可靠且可维护代码的基础。通过显式地声明变量的类型,开发者可以在编译时捕获潜在的错误,避免在运行时出现意外的类型错误。TypeScript 提供了丰富的内置数据类型,如 NumberStringArrayTupleMap 等,以及高级类型如 Union Types,这些类型帮助开发者更好地组织和处理数据。

下面作者将逐一进行介绍!


一、基础数据类型

1. Number 类型

① 基本用法

在 TypeScript 中,Number 类型用于表示数值数据,包括整数和浮点数。Number 类型是 JavaScript 中 Number 对象的静态类型表示。以下是 Number 类型的基本用法:

  • 整数和浮点数的声明
let num1: number = 123; // 整数
let num2: number = 0.456; // 浮点数
  • 特殊值
let notANumber: number = NaN;
let infinity: number = Infinity;
let negativeInfinity: number = -Infinity;
- `NaN`(Not-a-Number):表示一个非数字值。
- `Infinity` 和 `-Infinity`:分别表示正无穷大和负无穷大。
  • 不同进制表示法
let binary: number = 0b1010; // 二进制
let octal: number = 0o744; // 八进制
let decimal: number = 6; // 十进制
let hex: number = 0xf00d; // 十六进制
  • 二进制:以 0b0B 开头。
  • 八进制:以 0o0O 开头。
  • 十进制:直接表示。
  • 十六进制:以 0x0X 开头。
② 内置属性

Number 类型在 TypeScript 中有一些内置属性,这些属性提供了关于数值范围和特殊值的信息。以下是一些常用的内置属性:

属性名描述
Number.MAX_VALUE表示 JavaScript 中最大的正数,约为 1.8e+308。
Number.MIN_VALUE表示 JavaScript 中最小的正数(即最接近 0 的正数),约为 5e-324。
Number.NaN表示 “Not-a-Number” 值。
Number.POSITIVE_INFINITY表示正无穷大。
Number.NEGATIVE_INFINITY表示负无穷大。
Number.EPSILON表示 1 和比 1 大的最小浮点数之间的差。
Number.MAX_SAFE_INTEGER表示在 JavaScript 中可以精确表示的最大整数,即 2^53 - 1。
Number.MIN_SAFE_INTEGER表示在 JavaScript 中可以精确表示的最小整数,即 -(2^53 - 1)。
③ 内置方法

Number 类型在 TypeScript 中有一些内置方法,这些方法提供了对数值进行操作和检查的功能。以下是一些常用的内置方法:

方法名描述
Number.isFinite()检查传入的参数是否是有限的数字。如果参数是有限的数字,则返回 true,否则返回 false
Number.isInteger()检查传入的参数是否是整数。如果参数是整数,则返回 true,否则返回 false
Number.isNaN()检查传入的参数是否是 NaN。如果参数是 NaN,则返回 true,否则返回 false
Number.isSafeInteger()检查传入的参数是否是安全整数。如果参数是安全整数,则返回 true,否则返回 false
Number.parseFloat()将字符串解析为浮点数。
Number.parseInt()将字符串解析整数。
Number.prototype.toFixed()将数字格式化为字符串,并保留到小数点后指定位数。
Number.prototype.toExponential()将数字转换为指数表示法。
Number.prototype.toPrecision()将数字格式化为字符串,并按指定的精度。
Number.prototype.toString()将数字转换为字符串。可以指定基数。

代码示例

// Number.isFinite()
let finiteNumber = Number.isFinite(1000); // true
let infiniteNumber = Number.isFinite(Infinity); // false
console.log(finiteNumber, infiniteNumber);// Number.isInteger()
let integerNumber = Number.isInteger(1000); // true
let floatNumber = Number.isInteger(1000.5); // false
console.log(integerNumber, floatNumber);// Number.isNaN()
let notANumber = Number.isNaN(NaN); // true
let isANumber = Number.isNaN(1000); // false
console.log(notANumber, isANumber);// Number.isSafeInteger()
let safeInteger = Number.isSafeInteger(Math.pow(2, 53) - 1); // true
let unsafeInteger = Number.isSafeInteger(Math.pow(2, 53)); // false
console.log(safeInteger, unsafeInteger);// Number.parseFloat()
let floatFromString = Number.parseFloat("1000.5"); // 1000.5
console.log(floatFromString);// Number.parseInt()
let integerFromString = Number.parseInt("1000", 10); // 1000
console.log(integerFromString);// Number.prototype.toFixed()
let num1: number = 123.456;
console.log(num1.toFixed(2)); // "123.46"// Number.prototype.toExponential()
let num2: number = 123456;
console.log(num2.toExponential(2)); // "1.23e+5"// Number.prototype.toPrecision()
let num3: number = 123.456;
console.log(num3.toPrecision(2)); // "1.2e+2"// Number.prototype.toString()
let num4: number = 123;
console.log(num4.toString(10)); // "123"
④ 注意事项
  • IEEE 754 双精度浮点数标准的影响
    TypeScript 中的 Number 类型是基于 IEEE 754 双精度浮点数标准实现的。这意味着它不能精确表示所有的实数,特别是对于非常大或非常小的数,或者需要高精度的计算(如金融计算)时,可能会出现精度问题。例如:
let a: number = 0.1;
let b: number = 0.2;
let sum: number = a + b;
console.log(sum); // 0.30000000000000004

在这个例子中,0.1 + 0.2 的结果并不是精确的 0.3,而是 0.30000000000000004。这是由于浮点数在计算机中的表示方式导致的精度损失。

法。

2. String 类型

① 基本用法

在 TypeScript 中,String 类型用于表示文本数据。字符串可以使用单引号(')、双引号(")或反引号(```)来创建。反引号用于创建模板字符串,模板字符串可以跨越多行并嵌入表达式。以下是 String 类型的基本用法:

  • 单引号、双引号、反引号的使用
let str1: string = 'Hello, world'; // 使用单引号
let str2: string = "Hello, world"; // 使用双引号
let str3: string = `Hello,
world`; // 使用反引号创建多行字符串
  • 模板字符串和嵌入表达式
    模板字符串允许在字符串中嵌入表达式,表达式使用 ${} 语法。
let name: string = 'world';
let str4: string = `Hello, ${name}`; // 嵌入表达式
console.log(str4); // 输出 "Hello, world"
② 内置属性

String 类型在 TypeScript 中有一个内置属性 length,用于返回字符串的长度。

属性名描述
length返回字符串的长度。

代码示例

let str: string = "Hello, TypeScript!";
console.log(str.length); // 输出 18
③ 内置方法

String 类型在 TypeScript 中有许多内置方法,这些方法提供了对字符串进行操作和检查的功能。以下是一些常用的内置方法:

方法名描述
charAt(index)返回字符串中指定索引位置的字符。
charCodeAt(index)返回字符串中指定索引位置的字符的 Unicode 编码。
concat(...strings)连接两个或多个字符串,并返回一个新字符串。
indexOf(searchValue, fromIndex?)返回字符串中第一次出现指定值的索引,如果没有找到则返回 -1。
slice(start?, end?)提取字符串的一个片段,并返回一个新字符串。
substring(start, end?)提取字符串的一个子串,并返回一个新字符串。
toUpperCase()将字符串转换为大写。
toLowerCase()将字符串转换为小写。

代码示例

// charAt()
let str: string = "Hello, TypeScript!";
console.log(str.charAt(0)); // 输出 'H'// charCodeAt()
console.log(str.charCodeAt(0)); // 输出 72// concat()
let str1: string = "Hello, ";
let str2: string = "TypeScript!";
console.log(str1.concat(str2)); // 输出 'Hello, TypeScript!'// indexOf()
console.log(str.indexOf("Type")); // 输出 7// slice()
console.log(str.slice(0, 5)); // 输出 'Hello'// substring()
console.log(str.substring(0, 5)); // 输出 'Hello'// toUpperCase()
console.log(str.toUpperCase()); // 输出 'HELLO, TYPESCRIPT!'// toLowerCase()
console.log(str.toLowerCase()); // 输出 'hello, typescript!'
④ 注意事项
  • 字符串的不可变性
    在 TypeScript 中,字符串是不可变的(immutable),这意味着一旦字符串被创建,它的值就不能被改变。任何对字符串的操作都会返回一个新的字符串,而不会修改原始字符串。例如:
let str: string = "Hello";
str.toUpperCase(); // 返回一个新的字符串 "HELLO",但不会修改 str
console.log(str); // 输出 "Hello"

在这个例子中,toUpperCase() 方法返回了一个新的字符串 "HELLO",但原始字符串 str 的值仍然是 "Hello"

3. Array 类型

① 基本用法

在 TypeScript 中,Array 类型用于表示一系列相同类型元素的数据结构。数组可以存储多个值,并且可以通过索引访问这些值。以下是 Array 类型的基本用法:

  • 数组的声明和初始化
    数组可以通过多种方式声明和初始化。最常见的方式是使用数组字面量和数组构造函数。
// 使用数组字面量
let arr1: number[] = [1, 2, 3, 4, 5];// 使用数组构造函数
let arr2: Array<number> = new Array(1, 2, 3, 4, 5);
② 内置属性

Array 类型在 TypeScript 中有一个内置属性 length,用于返回数组的长度。

属性名描述
length返回数组的长度。

代码示例

let arr: number[] = [1, 2, 3, 4, 5];
console.log(arr.length); // 输出 5
③ 内置方法

Array 类型在 TypeScript 中有许多内置方法,这些方法提供了对数组进行操作和检查的功能。以下是一些常用的内置方法:

方法名描述
push(...items)将一个或多个元素添加到数组的末尾,并返回数组新的长度。
pop()移除数组的最后一个元素并返回该元素。
shift()移除数组的第一个元素并返回该元素。
unshift(...items)将一个或多个元素添加到数组的开头,并返回数组新的长度。
indexOf(searchElement, fromIndex?)返回数组中第一次出现指定元素的索引,如果没有找到则返回 -1。
splice(start, deleteCount?, ...items)从数组中移除元素,并在指定位置添加新的元素。
slice(start?, end?)提取数组的一个片段,并返回一个新数组。
forEach(callbackfn)对数组的每个元素执行一次提供的函数。
map(callbackfn)创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后的返回值。
filter(callbackfn)创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
reduce(callbackfn, initialValue?)对数组中的每个元素执行一个 reducer 函数,将其结果汇总为单个返回值。
reduceRight(callbackfn, initialValue?)从右到左对数组中的每个元素执行一个 reducer 函数,将其结果汇总为单个返回值。
find(callbackfn)返回数组中满足提供的测试函数的第一个元素的值,否则返回 undefined
findIndex(callbackfn)返回数组中满足提供的测试函数的第一个元素的索引,否则返回 -1。
some(callbackfn)测试数组中是否至少有一个元素通过由提供的函数实现的测试。
every(callbackfn)测试数组中的所有元素是否都通过了由提供的函数实现的测试。
join(separator?)将数组的所有元素连接成一个字符串,可指定分隔符。
reverse()反转数组中元素的顺序。
sort(compareFunction?)对数组的元素进行排序,并返回排序后的数组。
concat(...arrays)合并两个或多个数组,并返回一个新数组。
fill(value, start?, end?)用一个固定值填充数组中从起始索引到终止索引的全部元素。
copyWithin(target, start?, end?)将数组的一部分浅复制到同一数组中的另一个位置,并返回它,不会改变数组的长度。
entries()返回一个新的数组迭代器对象,该对象包含数组中每个索引的键/值对。
keys()返回一个新的数组迭代器对象,该对象包含数组中每个索引的键。
values()返回一个新的数组迭代器对象,该对象包含数组中每个索引的值。

代码示例

// push()
let arr: number[] = [1, 2, 3];
arr.push(4, 5);
console.log(arr); // 输出 [1, 2, 3, 4, 5]// pop()
let lastElement = arr.pop();
console.log(lastElement); // 输出 5
console.log(arr); // 输出 [1, 2, 3, 4]// shift()
let firstElement = arr.shift();
console.log(firstElement); // 输出 1
console.log(arr); // 输出 [2, 3, 4]// unshift()
arr.unshift(1, 2);
console.log(arr); // 输出 [1, 2, 2, 3, 4]// indexOf()
console.log(arr.indexOf(3)); // 输出 3// splice()
arr.splice(2, 1, 6); // 从索引 2 开始移除一个元素,然后添加元素 6
console.log(arr); // 输出 [1, 2, 6, 3, 4]// slice()
let slicedArr = arr.slice(1, 4);
console.log(slicedArr); // 输出 [2, 6, 3]// forEach()
arr.forEach((value, index) => {console.log(`Index: ${index}, Value: ${value}`);
});
// 输出:
// Index: 0, Value: 1
// Index: 1, Value: 2
// Index: 2, Value: 6
// Index: 3, Value: 3
// Index: 4, Value: 4// map()
let doubledArr = arr.map(value => value * 2);
console.log(doubledArr); // 输出 [2, 4, 12, 6, 8]// filter()
let filteredArr = arr.filter(value => value > 3);
console.log(filteredArr); // 输出 [6, 4]// reduce()
let sum = arr.reduce((acc, value) => acc + value, 0);
console.log(sum); // 输出 16// reduceRight()
let sumRight = arr.reduceRight((acc, value) => acc + value, 0);
console.log(sumRight); // 输出 16// find()
let foundElement = arr.find(value => value > 3);
console.log(foundElement); // 输出 6// findIndex()
let foundIndex = arr.findIndex(value => value > 3);
console.log(foundIndex); // 输出 2// some()
let hasGreaterThan3 = arr.some(value => value > 3);
console.log(hasGreaterThan3); // 输出 true// every()
let allGreaterThan0 = arr.every(value => value > 0);
console.log(allGreaterThan0); // 输出 true// join()
let joinedStr = arr.join("-");
console.log(joinedStr); // 输出 "1-2-6-3-4"// reverse()
arr.reverse();
console.log(arr); // 输出 [4, 3, 6, 2, 1]// sort()
arr.sort((a, b) => a - b);
console.log(arr); // 输出 [1, 2, 3, 4, 6]// concat()
let newArr = arr.concat([7, 8, 9]);
console.log(newArr); // 输出 [1, 2, 3, 4, 6, 7, 8, 9]// fill()
arr.fill(0, 2, 4);
console.log(arr); // 输出 [1, 2, 0, 0, 6]// copyWithin()
arr.copyWithin(0, 3, 5);
console.log(arr); // 输出 [0, 6, 0, 0, 6]// entries()
let entries = arr.entries();
for (let entry of entries) {console.log(entry);
}
// 输出:
// [0, 0]
// [1, 6]
// [2, 0]
// [3, 0]
// [4, 6]// keys()
let keys = arr.keys();
for (let key of keys) {console.log(key);
}
// 输出:
// 0
// 1
// 2
// 3
// 4// values()
let values = arr.values();
for (let value of values) {console.log(value);
}
// 输出:
// 0
// 6
// 0
// 0
// 6
④ 注意事项

④ 注意事项

  • 数组的动态性
    在 TypeScript 中,数组是动态的,这意味着数组的长度可以动态改变。你可以随时向数组中添加或删除元素。例如:
let arr: number[] = [1, 2, 3];
arr.push(4); // 添加元素
console.log(arr); // 输出 [1, 2, 3, 4]arr.pop(); // 删除元素
console.log(arr); // 输出 [1, 2, 3]

在这个例子中,数组的长度随着元素的添加和删除而动态变化。数组的动态性在许多应用中非常有用,例如在实现一个 TodoList 时,你可以动态地添加和删除待办事项:

let todoList: string[] = ["Buy groceries", "Clean the house"];// 添加新的待办事项
todoList.push("Walk the dog");
console.log(todoList); // 输出 ["Buy groceries", "Clean the house", "Walk the dog"]// 完成一个待办事项,将其从列表中移除
todoList.splice(1, 1); // 移除 "Clean the house"
console.log(todoList); // 输出 ["Buy groceries", "Walk the dog"]

在这个例子中,todoList 数组的长度随着待办事项的添加和完成而动态变化。这种动态性使得数组非常适合用于需要频繁更新和修改数据的应用场景。


二、高级数据类型

1. Map 对象

① 基本用法

在 TypeScript 中,Map 是一种键-值对的集合,其中键和值可以是任意类型。Map 对象允许你存储和检索数据,并且提供了一些内置方法来操作这些数据。以下是 Map 对象的基本用法:

  • 创建和初始化 Map
    Map 对象可以通过 new Map() 构造函数创建,并且可以通过传递一个包含键值对的数组来初始化。
// 创建一个空的 Map
let myMap = new Map<string, number>();// 使用数组初始化 Map
let initialMap = new Map<string, number>([["one", 1],["two", 2]
]);
② 内置方法

Map 对象在 TypeScript 中有许多内置方法,这些方法提供了对键值对进行操作和检查的功能。以下是一些常用的内置方法:

方法名描述
set(key, value)向 Map 中添加一个新的键值对。如果键已经存在,则更新其值。
get(key)根据键获取对应的值,如果键不存在则返回 undefined
has(key)检查 Map 中是否包含指定的键。如果键存在,则返回 true,否则返回 false
delete(key)从 Map 中移除指定键的键值对,如果键存在则返回 true,否则返回 false
clear()移除 Map 中的所有键值对。
forEach(callbackfn)对 Map 中的每个键值对执行一次提供的函数。
keys()返回一个包含 Map 中所有键的迭代器。
values()返回一个包含 Map 中所有值的迭代器。
entries()返回一个包含 Map 中所有键值对的迭代器。

代码示例

// 创建一个空的 Map
let myMap = new Map<string, number>();// set()
myMap.set("one", 1);
myMap.set("two", 2);
console.log(myMap); // 输出 Map { 'one' => 1, 'two' => 2 }// get()
console.log(myMap.get("one")); // 输出 1
console.log(myMap.get("three")); // 输出 undefined// has()
console.log(myMap.has("one")); // 输出 true
console.log(myMap.has("three")); // 输出 false// delete()
console.log(myMap.delete("one")); // 输出 true
console.log(myMap.delete("three")); // 输出 false
console.log(myMap); // 输出 Map { 'two' => 2 }// clear()
myMap.clear();
console.log(myMap); // 输出 Map {}// 重新初始化 Map
myMap.set("one", 1);
myMap.set("two", 2);// forEach()
myMap.forEach((value, key) => {console.log(`Key: ${key}, Value: ${value}`);
});
// 输出:
// Key: one, Value: 1
// Key: two, Value: 2// keys()
let keys = myMap.keys();
for (let key of keys) {console.log(key);
}
// 输出:
// one
// two// values()
let values = myMap.values();
for (let value of values) {console.log(value);
}
// 输出:
// 1
// 2// entries()
let entries = myMap.entries();
for (let entry of entries) {console.log(`Key: ${entry[0]}, Value: ${entry[1]}`);
}
// 输出:
// Key: one, Value: 1
// Key: two, Value: 2
③ 注意事项
  • Map 与对象的区别
    Map 对象与普通 JavaScript 对象(Object)有一些重要的区别:

代码示例

// Map 的键可以是任意类型
let map = new Map<any, any>();
map.set({}, "object key");
map.set(() => {}, "function key");
map.set(123, "number key");console.log(map.get({})); // 输出 undefined,因为 {} 是新的对象
console.log(map.get(123)); // 输出 "number key"// 对象的键只能是字符串或 Symbol
let obj: any = {};
obj[123] = "number key";
console.log(obj["123"]); // 输出 "number key",因为数字键被转换为字符串// Map 保留插入顺序
let map2 = new Map<string, number>();
map2.set("one", 1);
map2.set("two", 2);
map2.set("three", 3);map2.forEach((value, key) => {console.log(`Key: ${key}, Value: ${value}`);
});
// 输出:
// Key: one, Value: 1
// Key: two, Value: 2
// Key: three, Value: 3// 对象的键值对顺序不保证
let obj2: any = {one: 1,two: 2,three: 3
};Object.keys(obj2).forEach(key => {console.log(`Key: ${key}, Value: ${obj2[key]}`);
});
// 输出顺序可能不同,取决于 JavaScript 引擎
  • 键的类型
    * Map 的键可以是任意类型,包括对象、函数、基本类型等。
    * 对象的键只能是字符串或 Symbol 类型。
  • 顺序
    * Map 会保留键值对的插入顺序。
    * 对象的键值对顺序在不同 JavaScript 引擎中可能不同,且不保证顺序。
  • 性能
    * Map 在频繁的插入和删除操作中性能更好。
    * 对象在某些情况下可能更适合简单的键值存储。
  • 迭代
    * Map 提供了内置的迭代方法,如 keys()values()entries()
    * 对象需要使用 Object.keys()Object.values()Object.entries() 进行迭代。
④ 应用场景

Map 对象在许多实际应用场景中非常有用,特别是在需要高效地存储和检索键值对数据时。以下是一些常见的应用场景:

  • 缓存管理
    在需要缓存数据的应用中,Map 可以用来存储缓存数据,并根据键快速检索数据。
let cache = new Map<string, any>();function getData(key: string): any {if (cache.has(key)) {console.log("Cache hit");return cache.get(key);} else {console.log("Cache miss");let data = fetchDataFromServer(key); // 模拟从服务器获取数据cache.set(key, data);return data;}
}function fetchDataFromServer(key: string): any {// 模拟从服务器获取数据return `Data for ${key}`;
}console.log(getData("user1")); // 输出 "Cache miss" 和 "Data for user1"
console.log(getData("user1")); // 输出 "Cache hit" 和 "Data for user1"
  • 配置管理
    在需要管理配置项的应用中,Map 可以用来存储配置项,并根据键快速检索配置值。
let config = new Map<string, string>();
config.set("apiUrl", "https://api.example.com");
config.set("timeout", "5000");function getConfig(key: string): string | undefined {return config.get(key);
}console.log(getConfig("apiUrl")); // 输出 "https://api.example.com"
console.log(getConfig("timeout")); // 输出 "5000"
  • 事件管理
    在需要管理事件监听器的应用中,Map 可以用来存储事件名称和对应的处理函数。
let eventListeners = new Map<string, Function[]>();function on(eventName: string, handler: Function): void {if (!eventListeners.has(eventName)) {eventListeners.set(eventName, []);}eventListeners.get(eventName)!.push(handler);
}function emit(eventName: string, ...args: any[]): void {if (eventListeners.has(eventName)) {eventListeners.get(eventName)!.forEach(handler => handler(...args));}
}on("click", () => console.log("Button clicked"));
on("click", () => console.log("Button clicked again"));emit("click"); // 输出 "Button clicked" 和 "Button clicked again"
  • 数据映射
    在需要将一种数据类型映射到另一种数据类型的应用中,Map 可以用来存储映射关系。
let userRoles = new Map<string, string>();
userRoles.set("user1", "admin");
userRoles.set("user2", "editor");function getUserRole(userId: string): string | undefined {return userRoles.get(userId);
}console.log(getUserRole("user1")); // 输出 "admin"
console.log(getUserRole("user2")); // 输出 "editor"

通过以上详细的介绍和代码示例,读者可以更好地理解和掌握 TypeScript 中的 Map 对象及其相关属性和方法,并了解其在实际应用中的使用场景。

2. 元组(Tuple)

① 基本用法

在 TypeScript 中,元组(Tuple)是一种固定长度且每个元素类型可以不同的数组。元组允许你存储多个不同类型的值,并且每个位置的类型是固定的。以下是元组的基本用法:

  • 元组的声明和初始化
    元组可以通过数组字面量来声明和初始化。元组的类型注解使用方括号 [],并在其中指定每个元素的类型。
// 声明一个包含字符串、数字和布尔值的元组
let tuple: [string, number, boolean] = ["Hello", 42, true];// 访问元组中的元素
console.log(tuple[0]); // 输出 "Hello"
console.log(tuple[1]); // 输出 42
console.log(tuple[2]); // 输出 true
② 内置属性

Tuple 类型在 TypeScript 中有一个内置属性 length,用于返回元组的长度。

属性名描述
length返回元组的长度。

代码示例

let tuple: [string, number, boolean] = ["Hello", 42, true];
console.log(tuple.length); // 输出 3
③ 内置方法

Tuple 类型在 TypeScript 中有一些内置方法,这些方法提供了对元组进行操作和检查的功能。以下是一些常用的内置方法:

方法名描述
concat(...items: ConcatArray[]): T[]连接两个或多个数组或值,并返回一个新数组。
join(separator?: string): string将元组的所有元素连接成一个字符串,可指定分隔符。
slice(start?: number, end?: number): T[]提取元组的一个片段,并返回一个新数组。
toString(): string将元组转换为字符串。
indexOf(searchElement: T, fromIndex?: number): number返回元组中第一次出现指定元素的索引,如果没有找到则返回 -1。
push(...items: T[]): number向元组末尾添加一个或多个元素,并返回新的长度。
`pop(): Tundefined`

代码示例

// 声明一个元组
let tuple: [string, number, boolean] = ["Hello", 42, true];// concat()
let newTuple = tuple.concat(["world", 123]);
console.log(newTuple); // 输出 ["Hello", 42, true, "world", 123]// join()
let joinedStr = tuple.join("-");
console.log(joinedStr); // 输出 "Hello-42-true"// slice()
let slicedTuple = tuple.slice(1, 2);
console.log(slicedTuple); // 输出 [42]// toString()
let tupleStr = tuple.toString();
console.log(tupleStr); // 输出 "Hello,42,true"// indexOf()
console.log(tuple.indexOf(42)); // 输出 1// push()
tuple.push("world");
console.log(tuple); // 输出 ["Hello", 42, true, "world"]// pop()
let lastElement = tuple.pop();
console.log(lastElement); // 输出 "world"
console.log(tuple); // 输出 ["Hello", 42, true]
④ 注意事项
  • 元组的固定长度特性
    元组的一个重要特性是它的长度是固定的,一旦声明,元组的长度就不能改变。这意味着你不能随意添加或删除元组中的元素。例如:
let tuple: [string, number, boolean] = ["Hello", 42, true];// 尝试添加元素会导致错误
// tuple.push("world"); // 错误:类型 '[string, number, boolean]' 上不存在属性 'push'// 尝试删除元素会导致错误
// tuple.pop(); // 错误:类型 '[string, number, boolean]' 上不存在属性 'pop'

元组的固定长度特性使得它在需要固定结构的数据场景中非常有用,例如函数返回多个值时:

function getUserInfo(): [string, number, boolean] {return ["Alice", 30, true];
}let userInfo = getUserInfo();
console.log(userInfo[0]); // 输出 "Alice"
console.log(userInfo[1]); // 输出 30
console.log(userInfo[2]); // 输出 true

3. 联合类型(Union Types)

① 基本用法

在 TypeScript 中,联合类型(Union Types)是指一个变量可以具有多种不同的类型。联合类型使用竖线 | 来分隔不同的类型。以下是联合类型的基本用法:

  • 联合类型的声明
    联合类型可以通过在类型注解中使用竖线 | 来声明。例如,一个变量可以是字符串或数字类型:
let value: string | number;value = "Hello"; // 合法
value = 42; // 合法
// value = true; // 错误:类型 'true' 不能赋值给类型 'string | number'
② 内置方法

联合类型在 TypeScript 中有一些内置方法和技巧,可以帮助你在使用联合类型时更安全地处理属性和方法。以下是一些常用的内置方法:

方法名描述
typeof 类型保护使用 typeof 类型保护来缩小联合类型的范围。通过检查变量的类型,可以在相应分支中安全地访问特定类型的属性和方法。
类型断言使用类型断言来告诉 TypeScript 编译器一个变量的确切类型,从而可以安全地访问该类型的属性和方法。
共有属性检查在联合类型上使用共有属性,确保所有类型都具有相同的属性。
函数重载通过函数重载定义多个函数签名,使 TypeScript 能够根据输入值的类型正确调用相应的函数。

代码示例

// typeof 类型保护
function printLength(value: string | number): void {if (typeof value === "string") {console.log(value.length); // 在这个分支中,value 被 TypeScript 理解为字符串类型} else {console.log(value.toFixed(2)); // 在这个分支中,value 被 TypeScript 理解为数字类型}
}printLength("Hello"); // 输出 5
printLength(42); // 输出 "42.00"// 类型断言
let value: string | number = "Hello";
let len = (value as string).length; // 在这里使用类型断言将 value 明确指定为字符串类型
console.log(len); // 输出 5// 共有属性检查
type StringOrNumber = string | number;function printValue(value: StringOrNumber): void {console.log(value.toString()); // toString 是 string 和 number 共有的方法
}printValue("Hello"); // 输出 "Hello"
printValue(42); // 输出 "42"// 函数重载
function processValue(value: string): void;
function processValue(value: number): void;
function processValue(value: string | number): void {if (typeof value === "string") {console.log(value.toUpperCase());} else {console.log(value.toFixed(2));}
}processValue("Hello"); // 输出 "HELLO"
processValue(42); // 输出 "42.00"
③ 注意事项
  • 联合类型的类型安全
    在使用联合类型时,确保类型安全非常重要。联合类型的类型安全可以通过以下几种方式来实现:
    • 类型保护
      使用 typeofinstanceof 或其他类型保护机制来缩小联合类型的范围,确保在特定分支中变量的类型是明确的。
function printLength(value: string | number): void {if (typeof value === "string") {console.log(value.length); // value 是字符串类型} else {console.log(value.toFixed(2)); // value 是数字类型}
}
- **类型断言**:  

在某些情况下,你可以使用类型断言来明确指定变量的类型,从而避免类型错误。

let value: string | number = "Hello";
let len = (value as string).length; // 类型断言
console.log(len); // 输出 5
- **共有属性检查**:  

确保在联合类型上使用共有属性,避免访问不存在的属性。

type StringOrNumber = string | number;function printValue(value: StringOrNumber): void {console.log(value.toString()); // toString 是 string 和 number 共有的方法
}
- **函数重载**:  

通过函数重载定义多个函数签名,使 TypeScript 能够根据输入值的类型正确调用相应的函数。

function processValue(value: string): void;
function processValue(value: number): void;
function processValue(value: string | number): void {if (typeof value === "string") {console.log(value.toUpperCase());} else {console.log(value.toFixed(2));}
}

相关链接

  • 项目地址:TypeScript-CookBook
  • 相关文档:专栏地址
  • 作者主页:GISer Liu-CSDN博客

thank_watch

如果觉得我的文章对您有帮助,三连+关注便是对我创作的最大鼓励!或者一个star🌟也可以😂.

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

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

相关文章

Matlab simulink建模与仿真 第十九章(生成C代码)

一、Configuration Parameters模型参数配置 1、仿真时间 &#xff08;1&#xff09;在Solver选项卡中可以设置仿真的起始时间和结束时间&#xff0c;一般起始时间设为0&#xff0c;而结束时间按需设置。 &#xff08;2&#xff09;如果希望仿真不会自动暂停&#xff08;也就…

Qwen大型语言模型系列的最新成果 ----Qwen2.5

通义千问2.5-7B-Instruct-GGUF 模型库 (modelscope.cn) apt install git-lfsgit lfs installgit clone https://www.modelscope.cn/qwen/Qwen2.5-7B-Instruct-GGUF.git

(done) 声音信号处理基础知识(3) (一个TODO: modulation 和 timbre 的关联)(强度、响度、音色)

来源&#xff1a;https://www.youtube.com/watch?vJkoysm1fHUw sound power 通常可以被认为是能量传输的速率 声源往所有方向传输的每时间单位能量 用 瓦特(W) 作为单位测量 Sound intensity 声音强度&#xff0c;每单位面积的 sound power W/m^2 人类实际上能听到非常小强…

Mybatis+Druid+MybatisPlus多数据源配置

MybatisDruidMybatisPlus多数据源配置 平常我们使用的是 properties 或者 yaml 来配置数据库的地址、用户名、密码等 但是这样只能配置一个数据源 现在我们想在一个项目里面配置多个数据源&#xff0c;那么我们就需要配置自己的配置类 配置类和配置文件 Mybatismysqldruid配置…

此框架你到底了解多少???

1.简述对Spring中IOC/DI的理解 IOC&#xff1a;控制反转&#xff0c;将创建和管理的对象的任务交给外部的Spring容器 DI&#xff1a;依赖注入&#xff0c;对象之间存在依赖关系&#xff0c;创建对象时&#xff0c;对其依赖的对应直接进行赋值 2.有哪些依赖注入的方式 基于注…

在线教程丨1 步生成 SOTA 级别图像,Hyper-SD 一键启动教程上线!

近年来&#xff0c;扩散模型在文生图任务中得到了广泛的应用&#xff0c;但其在实现高质量图像生成的过程中&#xff0c;通常需要多步推理进行去噪&#xff0c;这显然大大增加了计算资源成本。 针对于此&#xff0c;研究人员引入蒸馏算法&#xff0c;推出了扩撒感知蒸馏算法来…

超实用的 Typora 插件

&#x1f33c;&#x1f4da;Typora 是一款高效、易用且跨平台的 Markdown 编辑器和阅读器&#xff0c;其具有小巧、快速、实时预览等特点&#xff0c;非常受大家的欢迎。今天给大家推荐一款如虎添翼的 Typora 插件(Typora Plugin)&#xff0c;它可以通过插件增强 Typora 的功能…

什么是调制?FM 和 AM 有什么区别?

来源&#xff1a;https://www.bilibili.com/video/BV1pp411d7Zg/?spm_id_fromautoNext&vd_source7a1a0bc74158c6993c7355c5490fc600 一张图说明一切 原因&#xff1a;低频信号传输距离很近&#xff0c;高频信号传输距离较远。 为了把低频信号传出去&#xff0c;需要把低…

【数据结构C语言】【入门】【首次万字详细解析】入门阶段数据结构可能用到的C语言知识,一章让你看懂数据结构!!!!!!!

前言&#xff1a;欢迎各位光临本博客&#xff0c;这里小编带你直接手撕入门阶段的数据结构的C语言知识&#xff0c;让你不再看见数据结构就走不动道。文章并不复杂&#xff0c;愿诸君耐其心性&#xff0c;忘却杂尘&#xff0c;道有所长&#xff01;&#xff01;&#xff01;&am…

图片马赛克处理(Java)

1.需求 给图片的指定区域打码给整张图片打码马赛克方格取色支持中心点取色和随机取色马赛克支持灰度处理 2.源码 package com.visy.utils;import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOE…

我们如何通过两个关键测试原则,进行自动化 Kubernetes 配置和Secret测试

现如今&#xff0c;一个上规模的应用程序几乎都会使用 Kubernetes 作为管理环境实现自动扩展、负载平衡&#xff08;auto scaling, load balancing &#xff09;等机制。与之相应的&#xff0c;我们通常会使用一个 repository 专门管理一个组织内部各项不同应用程序在各个环境的…

领夹麦克风怎么样,无线领夹麦克风哪个牌子好,家用麦克风推荐

​作为消费类电子产品&#xff0c;麦克风随着市场需求和技术进步&#xff0c;每年都有新产品系列涌现&#xff0c;特别是领夹麦克风&#xff0c;近年来经历了显著的市场变革和技术突破。从早期的新闻采访、节目录制和影视后期录音中常用的无线小蜜蜂话筒&#xff0c;到如今在网…

如何选择公司

前言&#xff1a; 了不起学弟&#xff1a;学长啊&#xff0c;我这手上有几个offer&#xff0c;有几家不同种类的公司&#xff0c;我这该怎么选啊。。。 了不起&#xff1a;这确实是在正在找工作的同学一定会遇到的问题&#xff0c;如何选择公司。那我就给你讲一讲吧。 正文&…

6张图掌握提示词工程师工作范围与工作技巧(提示词原理篇)

在人工智能的疆域中&#xff0c;提示词工程师扮演着至关重要的角色。他们精心设计的话语&#xff0c;是引导AI模型理解人类需求、激发创造力的关键。如同指挥官的号令&#xff0c;提示词工程师的每一个提问&#xff0c;都让AI的潜力得到释放&#xff0c;让技术与智慧的对话更加…

u-code-input结合u-keyboard实现支付密码+数字键盘

u-code-input结合u-keyboard实现支付密码数字键盘 一、需求描述、框架&#xff08;一&#xff09;技术框架&#xff08;二&#xff09;需求 二、效果图三、代码实现&#xff08;一&#xff09;u-code-input组件小改造&#xff08;二&#xff09;功能实现 一、需求描述、框架 &…

java 异常-Exception

异常的概念 Java 语言中&#xff0c;将程序执行中发生的不正常情况称为“异常”。&#xff08;开发过程中的语法错误和逻辑错误不是异常&#xff09; 执行过程中所发生的异常事件可分为两大类 &#xff08;1&#xff09;Error&#xff08;错误&#xff09;&#xff1a;Java 虚…

[Python]案例驱动最佳入门:股票分析 Python数据分析与可视化实战

在股票市场中&#xff0c;价格波动和投资决策紧密相连。通过数据分析&#xff0c;投资者可以识别市场趋势、价格波动背后的规律&#xff0c;并做出明智的投资决策。Python凭借其强大的数据处理和可视化功能&#xff0c;在金融市场分析中被广泛应用。本文将通过一个假设的股票市…

MySQL基础基础篇 - SQL

01 SQL通用语法 02 SQL分类 03 DDL语句 04 DML语句 05 DQL语句(单表查询) 05_01 学习总览 05_02 基本查询 05_03 条件查询 【应用实例】&#xff1a; 05_04 聚合函数 05_05 分组查询 05_06 排序查询 05_07 分页查询 【boss题目】&#xff1a; 05_08 执行顺序 06 DCL语句 【概…

如何设计出一个比较全面的测试用例

目录 1. 测试用例的基本要素(不需要执行结果) 2. 测试用例的给我们带来的好处 3. 用例编写步骤 4. 设计测试用例的方法 4.1 基于需求进行测试用例的设计 4.2 具体的设计方法 1.等价类 2.边界值 3.判定表&#xff08;因果图&#xff09; 4.正交表法 5.场景设计法 6.错误猜测…

JavaSE——String类

一、字符串构造 注意&#xff1a;String是引用类型&#xff0c;内部并不存储字符串本身。 有三种方式&#xff1a; public class Test1 {public static void main(String[] args) {// 使用常量串构造String s1 "hello java";System.out.println(s1);// 直接newSt…