快速开始React开发二
快速开始React开发(二)
快速开始React开发(二)
1、TypeScript简介
1.1、什么是TypeScript?
TypeScript 是JavaScript的 超集 ,它添加了 可选的静态类型 和 基于类的面向对象编程 等特性
TypeScript代码 最终会被编译成JavaScript代码 在浏览器中运行
1.2、为什么选择TypeScript?
- 静态类型检查 ,提前发现错误
- 更好的IDE支持,智能提示更强大
- 更容易维护 的代码结构
- 支持最新的JavaScript特性
2、环境准备
2.1、安装Node.js和TypeScript
安装node.js的传送门上一章里有,就不再赘述了
接下来安装下 TypeScript编译器
# 安装TypeScript编译器
npm install -g typescript
# 验证安装
tsc --version
此时环境应该是已经准备完毕了,React项目中我们已经自带了
typescript
,这里学习TypeScript另外新建一个简单空项目
2.2、创建第一个TypeScript文件
创建一个空的目录,使用Trae打开,创建一个后缀为
.ts
的文本文件,比如说
hello.ts
加入以下代码
// 定义一个问候函数,接受一个字符串类型的名字参数
function greet(name: string) {
// 使用模板字符串打印问候语
console.log(`Hello, ${name}!`);
}
// 调用 greet 函数,传入 "TypeScript" 作为参数
greet("TypeScript");
2.3、编译和运行
在当前目录打开控制台,输入
tsc
命令对刚刚编写的文件进行
编译
# 编译TypeScript文件
tsc hello.ts
执行完之后,就生成了一份同名的
.js
文件
使用
node
命令运行JS文件
# 运行生成的JavaScript文件
node hello.js
3、基本类型系统
3.1、基本类型
数字类型
TypeScript里的
所有数字都是浮点数
,其类型为
number
除了支持十进制和十六进制字面量,TypeScript还支持ECMAScript 2015中引入的二进制和八进制字面量
let decimal: number = 6; // 十进制
let hex: number = 0xf00d; // 十六进制
let binary: number = 0b1010; // 二进制
布尔类型
仅仅true和false两个值,用于进行逻辑判断
// 布尔类型
let isDone: boolean = false;
字符串
用于存储文本数据,可以使用
'
或者
"
包裹文本内容,使用反引号包裹后,可以使用
${}
嵌入表达式
// 字符串类型
let color: string = "blue";
let sentence: string = `The color is ${color}`;
any类型
可以用于对在编程阶段不清楚类型的值指定一个类型,通常这种值可能来源于 动态内容 ,比如用户的输入、三方代码等
如果我们
不希望类型检查器对其进行检查
,而是
直接通过编译检查
,可以使用
any
类型对变量进行标记
let notSure: any = 4;
notSure = "maybe a string";
let list: any[] = [1, true, "free"];
list[1] = 100; // 可以修改为任意类型
给了我们更大的灵活性,但同时也
失去了 TypeScript 的类型安全特性
,建议谨慎使用
any
类型
null和undefined
默认情况下
null
和
undefined
是
所有类型的子类型
,因此他俩可以赋值给其他类型
但是,如果指定
--strictNullChecks
时,
null
和
undefined
只能赋值给
void
和它们各自
// null 和 undefined 类型示例
let u: undefined = undefined; // undefined 类型只能赋值 undefined
let n: null = null; // null 类型只能赋值 null
二者也要注意意义上的区别:
undefined
:表示一个变量 未被赋值null
:表示一个变量 被明确地赋值为空
放一个空的文件
tsconfig.json
在当前目录下
let result: number; // 通常情况下null和undefined可以赋值给其他类型
result = null;
此时,再修改
tsconfig.json
中的编译配置
{
"compilerOptions": {
"strict": true, // 开启严格模式
},
}
开启
严格模式
后,
null
和
undefined
除了给自身外,只能赋值给
void
(
undefinded
可以,
null
不行)
鼓励尽可能地使用
--strictNullChecks
void类型
void
类型
表示没有任何类型
,一个函数没有任何返回值时,通常的返回值类型就是
void
function warnUser(): void {
console.log("This is a warning message");
// 不需要返回值
}
// void 类型变量只能赋值 undefined(在非严格模式下也可以赋值 null)
let unusable: void = undefined;
unknown类型
unknown
类型是TypeScript中的一个特殊类型,它表示任何值,但比
any
更安全
使用
unknown
类型时,我们
必须先进行类型检查或类型断言
才能对值进行操作
如果我们有一个
unknown
类型的变量,我们不能直接调用它的方法或访问它的属性,
必须先通过
typeof
、
instanceof
等类型检查或使用类型断言来确定具体类型
let userName: string;
let userInput: unknown;
if (typeof userInput === "string") {
userName = userInput; // 正确:已经进行类型检查
}
3.2、复合类型
数组
数组的特征是 多个类型相同的元素 组成的一个列表,成为一个复合变量,有两种方法进行定义:
第一种,在数组元素类型的后面跟上
[]
表示对应类型的数组
let arr: number[] = [1, 2, 3]; // number类型的数组
第二种,使用内置的
Array
接口配合泛型使用
Array<T>
let list: Array<number> = [1, 2, 3];
元组
元组用来表示一个 已知元素数量和类型的数组 , 各元素类型不必相同
let tuple: [string, number] = ["hello", 10];
枚举
枚举类型可以增加一组数值的 可读性 ,其中的变体默认从 0 开始编号,也可以手动赋值
可以通过枚举的值获取枚举的名字
enum Color {
Red,
Green,
Blue
}
let c: Color = Color.Green;
console.log(c); // 输出 1
console.log(Color[1]); // "Green"
3.3、高级类型
联合类型
联合类型指的是
多个类型组成的一个新类型
,使用符号
|
表示
比如两个类型,A和B,组合成联合类型为
A|B
,此时既可以赋值为A类型,也可以赋值为B类型
let value: string | number;
value = "Hello";
console.log(typeof value); // 此时是string
value = 123;
console.log(typeof value); // 此时是number
常用的用法比如将变量声明为 可空 的类型
let enName: string | null;
if (getInput()) { // 不确定的状态
enName = "Tom";
} else {
enName = null;
}
console.log(enName?.charAt(0)); // 通过?判空
交叉类型
交叉类型指的多个类型组成的一个新类型,使用符号
&
表示
感觉很奇怪啊,怎么既是A又是B?
let x: string & number;
这是什么?编译器觉得这不是个东西
其实它主要用于 对象的合成
type API = { // 网站接口信息
address: string;
port: number;
}
type RegisterInfo = { // 网站注册信息
name: string;
createdAt: Date;
}
let webInfo: API & RegisterInfo = { // 全量信息,两者内容拼接
address: "192.168.101.76",
port: 8080,
name: "Grace Under Pressure",
createdAt: new Date()
}
类型别名
使用
type
命令可以为一个类型指定别名
上一个例子里已经用到了,
API
、
RegisterInfo
所代表的其实就是别名,这是为了增加代码的可读性
不使用别名,直接使用右边的内容也可以,但是这样明显不够优雅
let webInfo: {
address: string;
port: number;
} & {
name: string;
createdAt: Date;
} = {
address: "192.168.101.76",
port: 8080,
name: "Grace Under Pressure",
createdAt: new Date(),
};