TypeScript中的基本类型详解:number, string, boolean等
一、TypeScript 中的 number 类型
在 TypeScript 中,number
类型用于表示数字,无论是整数还是浮点数。这一点与 JavaScript 类似,JavaScript 只有一种数字类型,即双精度 64 位二进制格式的值(Number
类型),TypeScript 继承了这一特性。
1.1 定义 number 类型变量
下面是定义 number
类型变量的基本方式:
let age: number;
age = 25;
在上述代码中,首先声明了一个名为 age
的变量,并指定其类型为 number
。然后将 25
赋值给 age
,这是一个合法的操作,因为 25
是一个数字。
1.2 数字的不同表示形式
JavaScript 和 TypeScript 支持多种数字表示形式,包括十进制、二进制、八进制和十六进制。
- 十进制:最常见的数字表示形式,例如
10
、25
、3.14
等。 - 二进制:以
0b
或0B
开头,例如:
let binaryNumber: number = 0b1010; // 二进制的 1010 等于十进制的 10
- 八进制:以
0o
或0O
开头(在严格模式下,JavaScript 从 ES6 开始,八进制字面量必须以0o
或0O
开头),例如:
let octalNumber: number = 0o12; // 八进制的 12 等于十进制的 10
- 十六进制:以
0x
或0X
开头,例如:
let hexadecimalNumber: number = 0xA; // 十六进制的 A 等于十进制的 10
1.3 数字的运算
number
类型支持基本的算术运算,如加法、减法、乘法、除法等。
let num1: number = 5;
let num2: number = 3;
let sum: number = num1 + num2;
let difference: number = num1 - num2;
let product: number = num1 * num2;
let quotient: number = num1 / num2;
console.log(`Sum: ${sum}`);
console.log(`Difference: ${difference}`);
console.log(`Product: ${product}`);
console.log(`Quotient: ${quotient}`);
上述代码定义了两个 number
类型的变量 num1
和 num2
,并进行了加法、减法、乘法和除法运算,最后将结果打印到控制台。
需要注意的是,在除法运算中,如果结果是无限循环小数,JavaScript 和 TypeScript 会以近似值表示。例如:
let result: number = 1 / 3;
console.log(result); // 输出 0.3333333333333333
1.4 特殊的数字值
- NaN:表示不是一个数字(Not a Number)。当进行无效的数学运算时,会返回
NaN
,例如:
let invalidDivision: number = 0 / 0;
console.log(invalidDivision); // 输出 NaN
NaN
有一个特殊的性质,即它与任何值(包括它自身)进行比较都返回 false
。
console.log(NaN === NaN); // 输出 false
可以使用 isNaN()
函数来判断一个值是否为 NaN
:
let value1: number = NaN;
let value2: number = 10;
console.log(isNaN(value1)); // 输出 true
console.log(isNaN(value2)); // 输出 false
- Infinity 和 -Infinity:
Infinity
表示正无穷大,-Infinity
表示负无穷大。当一个正数除以零会得到Infinity
,负数除以零会得到-Infinity
。
let positiveInfinity: number = 1 / 0;
let negativeInfinity: number = -1 / 0;
console.log(positiveInfinity); // 输出 Infinity
console.log(negativeInfinity); // 输出 -Infinity
二、TypeScript 中的 string 类型
string
类型用于表示文本数据。在 TypeScript 中,字符串可以用单引号('
)、双引号("
)或反引号(```)来表示。
2.1 定义 string 类型变量
let name1: string = 'John';
let name2: string = "Jane";
let message: string = `Hello, ${name1} and ${name2}`;
在上述代码中,name1
使用单引号定义,name2
使用双引号定义,这两种方式在功能上基本相同。而 message
使用反引号定义,这是 ES6 引入的模板字符串,可以在字符串中嵌入表达式,通过 ${}
语法。
2.2 字符串的基本操作
- 字符串拼接:可以使用
+
运算符或模板字符串进行字符串拼接。
let part1: string = 'Hello';
let part2: string = 'World';
let combined1: string = part1 + ', ' + part2;
let combined2: string = `${part1}, ${part2}`;
console.log(combined1);
console.log(combined2);
- 获取字符串长度:可以使用字符串的
length
属性获取字符串的长度。
let text: string = 'TypeScript';
console.log(text.length); // 输出 9
- 访问字符串中的字符:可以通过索引来访问字符串中的单个字符,索引从
0
开始。
let str: string = 'example';
console.log(str[0]); // 输出 'e'
console.log(str[1]); // 输出 'x'
需要注意的是,JavaScript 和 TypeScript 中的字符串是不可变的,即一旦创建,就不能修改其内容。例如:
let myStr: string = 'test';
myStr[0] = 'T'; // 这不会改变字符串,而是被忽略
console.log(myStr); // 仍然输出 'test'
如果要修改字符串,需要创建一个新的字符串,例如:
let original: string = 'test';
let modified: string = 'T' + original.slice(1);
console.log(modified); // 输出 'Test'
2.3 字符串的方法
JavaScript 和 TypeScript 为 string
类型提供了丰富的方法。
- 查找子字符串:
indexOf()
:返回指定子字符串在字符串中首次出现的位置,如果不存在则返回-1
。
let sentence: string = 'The quick brown fox jumps over the lazy dog';
let position: number = sentence.indexOf('fox');
console.log(position); // 输出 16
- `lastIndexOf()`:返回指定子字符串在字符串中最后一次出现的位置,如果不存在则返回 `-1`。
let anotherSentence: string = 'banana';
let lastPosition: number = anotherSentence.lastIndexOf('a');
console.log(lastPosition); // 输出 5
- `includes()`:判断字符串是否包含指定的子字符串,返回 `true` 或 `false`。
let textToCheck: string = 'TypeScript is great';
let containsType: boolean = textToCheck.includes('Type');
console.log(containsType); // 输出 true
- 字符串转换:
toUpperCase()
:将字符串转换为大写形式。
let lowerCaseStr: string = 'hello';
let upperCaseStr: string = lowerCaseStr.toUpperCase();
console.log(upperCaseStr); // 输出 'HELLO'
- `toLowerCase()`:将字符串转换为小写形式。
let upperCaseText: string = 'WORLD';
let lowerCaseText: string = upperCaseText.toLowerCase();
console.log(lowerCaseText); // 输出 'world'
- 字符串截取:
slice()
:提取字符串的一部分,并返回一个新的字符串,不会修改原字符串。它接受两个参数,起始索引(包括)和结束索引(不包括)。如果省略结束索引,则截取到字符串末尾。
let fullStr: string = 'TypeScript Tutorial';
let subStr1: string = fullStr.slice(0, 9); // 截取从索引 0 到 8 的字符
let subStr2: string = fullStr.slice(10); // 截取从索引 10 到末尾的字符
console.log(subStr1); // 输出 'TypeScript'
console.log(subStr2); // 输出 'Tutorial'
- `substring()`:与 `slice()` 类似,但它不接受负数参数。如果第一个参数大于第二个参数,`substring()` 会自动交换两个参数的值。
let strToSub: string = 'example';
let sub1: string = strToSub.substring(2, 5);
let sub2: string = strToSub.substring(5, 2); // 等同于 strToSub.substring(2, 5)
console.log(sub1); // 输出 'amp'
console.log(sub2); // 输出 'amp'
- `substr()`:提取从指定位置开始指定长度的子字符串。第一个参数是起始位置,第二个参数是长度。
let sourceStr: string = 'TypeScript';
let subString: string = sourceStr.substr(2, 3);
console.log(subString); // 输出 'ype'
三、TypeScript 中的 boolean 类型
boolean
类型只有两个值:true
和 false
。它通常用于逻辑判断。
3.1 定义 boolean 类型变量
let isDone: boolean = true;
let hasError: boolean = false;
在上述代码中,isDone
被赋值为 true
,hasError
被赋值为 false
,这两个变量的类型都是 boolean
。
3.2 在条件语句中使用 boolean 类型
boolean
类型常用于 if - else
、while
、for
等条件语句中。
let isLoggedIn: boolean = true;
if (isLoggedIn) {
console.log('Welcome, user!');
} else {
console.log('Please log in.');
}
在这个例子中,isLoggedIn
是一个 boolean
类型的变量,if
语句根据其值来决定执行哪一部分代码。
3.3 逻辑运算符与 boolean 类型
boolean
类型支持逻辑运算符,如 &&
(逻辑与)、||
(逻辑或)和 !
(逻辑非)。
- 逻辑与(&&):只有当两个操作数都为
true
时,结果才为true
,否则为false
。
let condition1: boolean = true;
let condition2: boolean = false;
let result1: boolean = condition1 && condition2;
console.log(result1); // 输出 false
let condition3: boolean = true;
let result2: boolean = condition1 && condition3;
console.log(result2); // 输出 true
- 逻辑或(||):只要两个操作数中有一个为
true
,结果就为true
,只有当两个操作数都为false
时,结果才为false
。
let cond1: boolean = true;
let cond2: boolean = false;
let res1: boolean = cond1 || cond2;
console.log(res1); // 输出 true
let cond3: boolean = false;
let res2: boolean = cond2 || cond3;
console.log(res2); // 输出 false
- 逻辑非(!):用于取反一个
boolean
值。如果操作数为true
,则结果为false
;如果操作数为false
,则结果为true
。
let flag: boolean = true;
let negatedFlag: boolean =!flag;
console.log(negatedFlag); // 输出 false
四、TypeScript 中的 null 和 undefined 类型
在 TypeScript 中,null
和 undefined
都有自己的类型,分别为 null
和 undefined
。它们表示值的缺失或未定义。
4.1 null 类型
null
表示一个空值,通常用于表示一个变量故意不指向任何对象。
let myNull: null = null;
在严格模式下,null
类型的值只能赋值给 null
类型的变量,例如:
let a: null = null;
// let b: number = null; // 这会报错,因为不能将 null 赋值给 number 类型
4.2 undefined 类型
undefined
表示一个未定义的值。当一个变量声明但未初始化时,它的值就是 undefined
。
let myVar: undefined;
console.log(myVar); // 输出 undefined
同样,在严格模式下,undefined
类型的值只能赋值给 undefined
类型的变量。
let c: undefined = undefined;
// let d: string = undefined; // 这会报错,因为不能将 undefined 赋值给 string 类型
4.3 在 TypeScript 中的特殊行为
在 TypeScript 的严格模式下,null
和 undefined
只能赋值给它们各自类型的变量或者 any
类型的变量。但是,在非严格模式下,null
和 undefined
可以赋值给其他类型的变量,这可能会导致运行时错误。为了避免这种情况,建议始终使用严格模式。
在实际开发中,经常需要检查变量是否为 null
或 undefined
,以避免潜在的错误。例如:
let maybeNull: string | null = null;
if (maybeNull!== null) {
console.log(maybeNull.length);
}
在上述代码中,通过 !== null
检查 maybeNull
是否为 null
,只有在不为 null
的情况下才访问其 length
属性,从而避免了 null
引用错误。
五、TypeScript 中的 void 类型
void
类型表示没有任何类型。它通常用于函数返回值,表示该函数不返回任何值。
5.1 函数返回 void 类型
function logMessage(message: string): void {
console.log(message);
}
在上述代码中,logMessage
函数接受一个 string
类型的参数 message
,并将其打印到控制台,但该函数没有返回值,所以其返回类型被指定为 void
。
5.2 void 类型变量
虽然 void
类型主要用于函数返回值,但也可以声明 void
类型的变量。不过,由于 void
表示没有值,这样的变量只能被赋值为 null
(在非严格模式下)或 undefined
。
let myVoid: void;
myVoid = undefined;
// myVoid = 10; // 这会报错,因为不能将 number 类型赋值给 void 类型
六、TypeScript 中的 never 类型
never
类型表示永远不会出现的值的类型。它通常用于函数抛出异常或永远不会返回的函数。
6.1 抛出异常的函数
function throwError(message: string): never {
throw new Error(message);
}
在上述代码中,throwError
函数总是抛出一个错误,永远不会正常返回,所以其返回类型为 never
。
6.2 无限循环的函数
function infiniteLoop(): never {
while (true) {
// 无限循环
}
}
infiniteLoop
函数进入一个无限循环,永远不会结束,因此也不会返回,其返回类型也是 never
。
6.3 never 类型的应用场景
never
类型在类型推断中非常有用。例如,当一个函数根据条件返回不同类型的值时,如果某个条件分支永远不会发生,可以将该分支的返回类型指定为 never
,有助于 TypeScript 进行更准确的类型推断。
function getValue(isString: boolean): string | number {
if (isString) {
return 'Hello';
} else {
return 10;
}
// 以下代码永远不会执行,所以可以返回 never 类型
return throwError('This code should never be reached');
}
七、TypeScript 中的 any 类型
any
类型表示可以是任何类型的值。当你不确定一个变量的类型,或者你希望它能够接受任意类型的值时,可以使用 any
类型。
7.1 定义 any 类型变量
let myAny: any = 'Hello';
myAny = 10;
myAny = true;
在上述代码中,myAny
被定义为 any
类型,因此可以赋值为字符串、数字、布尔值等任何类型的值。
7.2 在函数参数和返回值中使用 any 类型
function printValue(value: any) {
console.log(value);
}
let result: any = printValue('Test');
在 printValue
函数中,参数 value
的类型为 any
,这意味着可以传入任何类型的值。函数的返回值也被推断为 any
类型,因为在函数内部没有明确返回值类型。
7.3 使用 any 类型的注意事项
虽然 any
类型提供了很大的灵活性,但过度使用它会失去 TypeScript 的类型检查优势,可能导致运行时错误。在实际开发中,应尽量避免使用 any
类型,除非在某些特殊情况下,比如与第三方库交互时,第三方库的类型信息不完整,此时可以使用 any
类型来绕过类型检查,但后续应尽量将其转换为具体的类型。
八、TypeScript 中的数组类型
TypeScript 支持多种方式定义数组类型。
8.1 类型 + 方括号表示法
可以通过在类型后面加上方括号 []
来表示数组类型。
let numbers: number[] = [1, 2, 3, 4, 5];
let strings: string[] = ['apple', 'banana', 'cherry'];
在上述代码中,numbers
是一个 number
类型的数组,strings
是一个 string
类型的数组。
8.2 数组泛型表示法
使用泛型 Array<类型>
来定义数组类型,例如:
let booleanArray: Array<boolean> = [true, false, true];
Array<boolean>
表示一个布尔类型的数组,与 boolean[]
的效果是一样的。
8.3 多维数组
可以通过多个方括号来表示多维数组。
let matrix: number[][] = [
[1, 2],
[3, 4]
];
在上述代码中,matrix
是一个二维数组,每个元素又是一个 number
类型的数组。
8.4 数组的方法
数组有许多常用的方法,如 push()
、pop()
、shift()
、unshift()
、splice()
、concat()
等。
- push():向数组末尾添加一个或多个元素,并返回新的数组长度。
let fruits: string[] = ['apple', 'banana'];
let newLength: number = fruits.push('cherry');
console.log(fruits); // 输出 ['apple', 'banana', 'cherry']
console.log(newLength); // 输出 3
- pop():从数组末尾删除一个元素,并返回被删除的元素。
let numbersList: number[] = [1, 2, 3];
let poppedNumber: number | undefined = numbersList.pop();
console.log(numbersList); // 输出 [1, 2]
console.log(poppedNumber); // 输出 3
- shift():从数组开头删除一个元素,并返回被删除的元素。
let words: string[] = ['hello', 'world'];
let shiftedWord: string | undefined = words.shift();
console.log(words); // 输出 ['world']
console.log(shiftedWord); // 输出 'hello'
- unshift():向数组开头添加一个或多个元素,并返回新的数组长度。
let colors: string[] = ['red', 'blue'];
let newLength2: number = colors.unshift('green');
console.log(colors); // 输出 ['green','red', 'blue']
console.log(newLength2); // 输出 3
- splice():用于添加或删除数组中的元素。它可以接受多个参数,第一个参数是起始位置,第二个参数是要删除的元素个数,后面的参数是要添加的元素。
let array: number[] = [1, 2, 3, 4, 5];
let removedElements: number[] = array.splice(2, 1, 6, 7);
console.log(array); // 输出 [1, 2, 6, 7, 4, 5]
console.log(removedElements); // 输出 [3]
- concat():用于合并两个或多个数组,并返回一个新的数组,不会修改原数组。
let arr1: number[] = [1, 2];
let arr2: number[] = [3, 4];
let combinedArray: number[] = arr1.concat(arr2);
console.log(combinedArray); // 输出 [1, 2, 3, 4]
九、TypeScript 中的元组类型
元组类型是 TypeScript 中特有的类型,它允许表示一个已知元素数量和类型的数组,但是各元素的类型不必相同。
9.1 定义元组类型变量
let user: [string, number] = ['John', 25];
在上述代码中,user
是一个元组类型的变量,它的第一个元素是 string
类型,第二个元素是 number
类型。
9.2 访问元组元素
可以通过索引来访问元组中的元素,与数组类似,但要注意索引不能超出元组定义的范围。
let userInfo: [string, number] = ['Jane', 30];
console.log(userInfo[0]); // 输出 'Jane'
console.log(userInfo[1]); // 输出 30
9.3 修改元组元素
元组中的元素可以被修改,前提是修改后的值符合元组定义的类型。
let profile: [string, boolean] = ['Bob', true];
profile[1] = false;
console.log(profile); // 输出 ['Bob', false]
9.4 元组的应用场景
元组通常用于表示一组相关但类型不同的数据。例如,在函数返回值中,可以使用元组来返回多个不同类型的值。
function getUser(): [string, number] {
return ['Alice', 28];
}
let [name, age] = getUser();
console.log(`Name: ${name}, Age: ${age}`);
在上述代码中,getUser
函数返回一个元组,通过解构赋值可以方便地获取元组中的各个元素。
十、TypeScript 中的枚举类型
枚举类型是 TypeScript 中为我们提供的一种用于定义命名常量集合的方式。它允许我们定义一组命名的数值常量。
10.1 数字枚举
enum Direction {
Up = 1,
Down,
Left,
Right
}
在上述代码中,定义了一个名为 Direction
的枚举类型。Up
被显式赋值为 1
,Down
、Left
和 Right
会自动递增,分别为 2
、3
和 4
。
可以通过枚举名和成员名来访问枚举值:
let myDirection: Direction = Direction.Right;
console.log(myDirection); // 输出 4
10.2 字符串枚举
除了数字枚举,还可以定义字符串枚举。
enum Status {
Success = 'success',
Failure = 'failure'
}
在字符串枚举中,每个成员都必须显式赋值。
10.3 异构枚举(不推荐)
虽然不常见,但也可以定义异构枚举,即成员既有数字类型又有字符串类型。
enum MixedEnum {
Value1 = 1,
Value2 = 'two'
}
不过,这种方式会使代码变得复杂且难以维护,不推荐使用。
10.4 反向映射
在数字枚举中,TypeScript 会自动为我们生成反向映射,即可以通过枚举值获取枚举名。
enum Color {
Red = 1,
Green,
Blue
}
let colorValue: Color = Color.Green;
let colorName: string = Color[colorValue];
console.log(colorName); // 输出 'Green'
10.5 枚举的应用场景
枚举常用于表示一组相关的常量,比如状态码、方向、颜色等。在代码中使用枚举可以提高代码的可读性和可维护性。例如,在处理 HTTP 响应状态码时,可以使用枚举来表示不同的状态:
enum HttpStatus {
Ok = 200,
Created = 201,
BadRequest = 400,
NotFound = 404
}
function handleResponse(status: HttpStatus) {
if (status === HttpStatus.Ok) {
console.log('Request successful');
} else if (status === HttpStatus.NotFound) {
console.log('Resource not found');
}
}
handleResponse(HttpStatus.NotFound);
通过上述对 TypeScript 基本类型的详细介绍,希望你对 number
、string
、boolean
等基本类型以及相关的特殊类型有了更深入的理解,能够在日常的前端开发中更加熟练和准确地使用 TypeScript 进行编程。在实际项目中,合理运用这些类型可以有效地减少类型相关的错误,提高代码的质量和可维护性。