之前我们讲解了TypeScript的安装过程,接下来,就让我们开始正式的学习TypeScript的基础类型
TypeScript的基础类型
我们前面说过,TypeScript是JavaScript的超集,那么TypeScript肯定是包含了我们JavaScript的基础类型,但是又不限于我们JavaScript的基础类型,TypeScript在 字符串(string)
、数字型(number)
、数组(array)
、布尔型(boolean)
、空(Null)
、未定义(Undefined)
、对象(Object)
类型的基础上。
还新增了枚举(enum)
、元组(tuple)
、Any 类型
、Unknown 类型
、Void 类型
、 Never 类型
、可选类型
Boolean、Number、String、Array、boolean类型
ts
// Boolean 类型
let Done: boolean = false;
// ES5:var Done = false;
// Number 类型
let count: number = 10;
// ES5:var count = 10;
//String 类型
let name: string = "Semliker";
// ES5:var name = 'Semlinker';
//Array 类型
let list: number[] = [1, 2, 3];
// ES5:var list = [1,2,3];
let list: Array<number> = [1, 2, 3]; // Array<number>泛型语法
// ES5:var list = [1,2,3];
Object类型
object对象类型可以用于描述一个对象
ts
//创建对象
let person: object = {
name: "zayyo",
age: 25,
isStudent: true
};
console.log(person); // 输出:{ name: 'zayyo', age: 25, isStudent: true }
interface(接口)
interface(接口)可以帮助我们定义对象的结构和类型。通过接口,我们可以指定对象应该包含哪些属性、方法以及它们的类型。帮助我们更好的进行代码的复用和优化
使用interface(接口) 来指定对象的类型
ts
interface Person {
name: string;
age: number;
isStudent: boolean;
}
let person: Person = {
name: "zayyo",
age: 25,
isStudent: true
};
console.log(person.name); // 输出:"zayyo"
?可选类型
我们的对象类型也可以指定哪些属性是可选的(可有可无),我们可以在属性的后面添加一个?:
ts
//声明可选属性
interface Person {
name: string;
age?: number; // age 是可选属性
}
let person: Person = { name: "Alice" }; // age 未定义
//可选类型结合可选链操作,使用可选链操作符访问属性
let person: Person | null = getPersonFromDatabase();
let age = person?.age;
Array 类型
数组类型可以帮助我们在单个变量中存储多个值。更方便地对这些值进行处理
ts
let list: number[] = [1, 2, 3];
// ES5:var list = [1,2,3];
Null 和 Undefined 类型
- null 类型表示一个空引用或者值的缺失。
- undefined 类型表示某个值未经初始化或者不存在。
在JavaScript中这两个类型是不能相互赋值的,但是在 TypeScript 中,这两种类型是可以互相赋值的。具体来说:
- 当我们启用了 "strictNullChecks(严格模式)" 时(默认情况下是启用状态),我们是不能将 null 或 undefined 赋给其他非兼容类型的变量。
ts
let myVar: string | null = null;
let myOtherVar: number | undefined = undefined;
// 可以赋给联合类型
myVar = "Hello";
myOtherVar = 10;
// null和undefined不允许直接赋给其他非兼容类型,
let someString: string = myVar; // 报错,因为变量myVa可能为null
let someNumber: number = myOtherVar; // 报错,因为变量myOtherVar可能为undefined
那如果我就是想要进行赋值,是不是就没有办法了呢?
我们可以通过条件判断进行赋值
ts
if (myVar !== null) {
someString = myVar;
}
if (myOtherVar !== undefined) {
someNumber= myOtherVa r;
}
- 但是,在非严格模式下,我们可以将 null 或 undefined 赋给任何类型的变量
ts
let myVar: string = null; // 不会报错
let myOtherVar: number = undefined; // 不会报错
// 可以直接赋给其他非兼容类型
let someString: string = myVar;
let someNumber: number = myOtherVar;
// 可以将 null 赋给 undefined 类型变量
myOtherVar = null;
// 可以将 undefined 赋给 null 类型变量
myVar = undefined;
Enum 枚举类型
num(枚举)类型用于定义一组命名常量。它可以帮助我们为这些常量赋予有意义的名称,帮助我们提高代码的可读性。
ts
//创建一个颜色枚举
enum Color {
Red,
Green,
Blue
}
console.log(Color.Green); // 输出:1 (Green 的索引值)
代码解释:
- 创建一个颜色枚举,并列出了三个可能的取值:Red、Green 和 Blue。
- 默认情况下,它们会依次被赋予索引值:0、1、2。(初始值为 0,其余的成员会从 1 开始自动增长)
- 我们直接打印对应的颜色,就会得到他们对应的索引
当然我们也可以设置 Color 的初始值,当然我们不仅可以赋值为Number也可以赋值为字符串类型。
但是我们要注意的是数字枚举相对字符串枚举多了 "反向映射"
ini
enum Color {
White,
Red = 3,
Green = 2,
Blue = "zayyo",
}
console.log(Color.Green); // 输出:2 (Green 的索引值)
console.log(Color[3]); // 输出:Red
console.log(Color[0]); // 输出:White
你可能会问Enum(枚举类型)到底有什么用途呢?接下来我们就看一个Enum(枚举类型)的妙用.
我们创建了一个函数来检查给定颜色是否属于 Color 枚举
ts
function isColorValid(color: Color): boolean {
return color === Color.Red || color === Color.Green || color === Color.Blue||color === Color.White;
}
console.log(isColorValid(Color.Red)); // 输出:true
console.log(isColorValid(Color.Yellow)); // 输出:false
Any 类型
在某些情况下,我们确实无法确定一个变量的类型,并且可能它会发生一些变化,这个时候我们就可以使用any类型。 在 TypeScript 中,任何类型都可以被归为 any 类型。这就让 any 类型成为了类型系统的顶级类型(也被称作全局超级类型)。
any类型有点像一种讨巧的TypeScript手段:我们可以对any类型的变量进行任何的操作,包括获取不存在的属性、方法。也可以给一个any类型的变量赋值任何的值,比如数字、字符串的值;
js
//定义 any 类型变量
let myVariable: any;
myVariable = "Hello"; // 可以赋予字符串类型值
myVariable = 10; // 可以赋予数字类型值
myVariable = true; // 可以赋予布尔类型值
//调用任意方法和属性
let myValue: any = "Hello";
console.log(myValue.toUpperCase()); // 输出 "HELLO"
我们可以在任何场景下,使用 any
类型,但是过度使用它可能破坏 TypeScript 的主要目标之一,静态类型安全。为了解决 any
带来的安全隐患,TypeScript 在3.0版本中 引入了 unknown
类型。
Unknown 类型
unknown是TypeScript中比较特殊的一种类型,它用于描述类型不确定的变量,它和any类型有点类似,所有类型都可以赋值给
any
,所有类型也都可以赋值给unknown
。但是在unknown类型的值上做任何事情都是不合法的。
可能这样说让你很难理解,让我们来看代码示例吧
ts
let myVariable: unknown;
myVariable = "Hello"; // 可以赋予字符串类型值
myVariable = 10; // 可以赋予数字类型值
myVariable = true; // 可以赋予布尔类型值
//但是将类型为 `unknown` 的值赋值给any除外的其他类型的变量是不被允许的。
let value2: boolean = myVariable; // Error
let value3: number = myVariable; // Error
let value5: string = myVariable; // Error
//同样类型为 `unknown` 的值也是不允许被执行操作的
myVariable.foo.bar; // Error
myVariable.trim(); // Error
myVariable(); // Error
new myVariable(); // Error
myVariable[0][1]; // Error
但是如果我们不得不对类型为Unknown
的值进行方法的调用时该怎么办呢?
我们可以进行类型检查和断言后,再进行调用。
ts
function processValue(value: unknown) {
if (typeof value === 'string') {
console.log(value.toUpperCase()); // 通过 typeof 检查后可以直接调用字符串方法
} else if (typeof value === 'number') {
console.log(Math.abs(value)); // 通过 typeof 检查后可以进行数学运算
} else {
console.log("Unknown type");
}
}
processValue("Hello"); // 输出 "HELLO"
processValue(10); // 输出 10
processValue(true); // 输出 "Unknown type"
// 使用 as 关键字进行断言
let strLength: number = (myVariable as string).length;
console.log(strLength); // 如果 myVariable 是字符串,则输出其长度
Tuple 元组类型
当我们需要将不同类型的元素存储在一个数组中时,就可以使用Tuple。其工作方式类似于数组,但是元组中每个元素都有自己特性的类型,我们根据索引值获取到的值可以确定对应的类型。而数组存放相同类型的元素。
ts
//## 声明和初始化元组
let person: [string, number, boolean];
person = ["Alice", 30, true];
//访问元祖元素
let name: string = person[0];
let age: number = person[1];
let isActive: boolean = person[2];
//展开运算符可以将一个元组中的元素添加到另一个元组中:
let moreInfo: [string, string] = ["New York", "USA"];
let extendedPerson: [...typeof person, ...typeof moreInfo] = [...person, ...moreInfo];
注意:在元组初始化的时候,我们必须提供每个属性的值,不然会出现报错
Void 类型
void 类型用于表示函数没有返回值。这意味着当您声明一个函数的返回类型为 void 时,该函数不会返回任何值。
function
console.log("Hello!");
}
注意:我们可以将undefined或null赋值给void类型,也就是函数可以返回undefined或 null
Never 类型
never 类型表示那些永远不会发生的值。它通常用于表示无法正常结束的函数或表达式,如抛出异常或进入无限循环。
当一个函数抛出异常,它就不会返回正常的结果,因此返回类型应为 never。
例如:
ts
function throwError(message: string): never {
throw new Error(message);
}
//函数 throwError 永远不会返回一个值,因为它总是抛出一个异常,导致代码无法继续执行。
当一个函数陷入无限循环,它也不会返回值,因此返回类型同样是 never。
例如:
ts
function infiniteLoop(): never {
while (true) {
// 无限循环
}
}