一、TypeScript概述
TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准(ES6 教程)。
TypeScript 由微软开发的自由和开源的编程语言。
TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。
编程语言,分为了"强类型语言"和"弱类型语言"。
强类型语言,对于数据类型要求非常严格,不允许不同类型的数据之间做隐式转换。
弱类型语言,对于数据类型要求不严格,不同的数据类型之间可以进行相互的转换。
-
静态类型检查
静态类型检查,指的是在代码编写的过程中,就开始对代码语法进行检查。也就是说,在代码运行之前,就可以检查出代码语法报错的地方。
因此我们前端开发,会慢慢选择用 TS 来代替 JS,就是因为 JS 是弱类型语言,而 TS 属于强类型语言。
1、安装typeScript
-
安装nodejs
官网:https://nodejs.p2hp.com/download/
nodejs的版本不要低于18
安装完成后在cmd窗口输入 node -v命令即可查看安装的nodejs信息
-
设置npm源
由于npm服务器在国外下载比较慢,一般会改为国内的镜像服务器。在cmd窗口输入如下命令
ininpm config set registry https://mirrors.huaweicloud.com/repository/npm/ #华为 或 npm config set registry https://registry.npmmirror.com #阿里
-
安装 typescript
ininpm i -g typescript
安装完成后我们可以使用 tsc 命令来执行 TypeScript 的相关代码,以下是查看版本号:
initsc -v Version 5.5.3
二、TypeScript 数据类型与变量
typeScript 程序由以下几个部分组成:
- 模块
- 函数
- 变量
- 语句和表达式
- 注释
TypeScript 区分大写和小写字符。
1、TypeScript 注释
- 单行注释 ( // ) − 在 // 后面的文字都是注释内容。
- 多行注释 (/* */) − 这种注释可以跨越多行。
ini
// 这是一个单行注释
/*
这是一个多行注释
这是一个多行注释
这是一个多行注释
*/
2、TypeScript数据类型
-
基本类型:数字 number、字符串 string、布尔值 boolean、空 null、未定义 undefined、唯一值 symbol、无穷大 bigInt
-
引用类型:**数组 array、对象 object、**元组 tuple、枚举 enum、函数 function
-
特殊类型:任意类型 any 、任意类型 unknown、void、never
-
高级类型:联合类型、交叉类型
3、TypeScript 变量
TypeScript 变量的命名规则:
- 变量名称可以包含数字和字母。
- 除了下划线 _ 和美元 $ 符号外,不能包含其他特殊字符,包括空格。
- 变量名不能以数字开头。
ini
语法:
var [变量名] : [类型] = 值;
示例:
var uname:string = "Runoob";
声明变量并初始值,但不设置类型,该变量可以是任意类型:
ini
语法:
var [变量名] = 值;
示例:
var uname = "Runoob";
a、基本类型
ini
var a: number = 1;
let b: string = 'hello';
const c: boolean = true;
let d: undefined = undefined;
let e: null = null;
b = 100; // 报错
b、数组
默认情况下,在 TS 中,要求数组内部只能保存同一个类型的数据
ini
let a: number[] = [1, 2, 3];let b: string[] = ['a', 'b'];
c、对象
可以通过 object 来设置对象的类型,但是设置成 object 类型后,不能单独访问对象内部的任意属性。
ini
let a: object = {id: 1,name:'张三'};
console.log(a.id); // 报错,不能确定 a 身上存在 id 属性
我们更常用的对象约束类型的方式,是针对对象中每一个属性以及每一个属性值的类型都一一进行约束:
ini
let a: { id: number, name: string } = {id: 1,name: '张三'}
console.log(a.id);
如果有某一些属性是可有可无 的,可以在约束类型时,在属性名后面添加 ?
:
ini
let a: { id: number, name: string, age?: number } = {id: 1,name:'张三',}
d、元组
从代码语法上来看,元组实际上就是数组,但是它和数组的区别在于,元组中可以报错不同类型的数据。
ini
let a: [number, string, number] = [1, '2', 3];
元组语法要求,数组中的每一条数据,都必须对应着一个类型。
e、枚举
当数据中有一些不确定含义的数字时,可以定义一个枚举类型,来描述每一个数字所对应的含义:
ini
enum GenderEnum {woman = 0,man = 1,unknown = 2}
定义好的枚举类型,既可以当作类型来用,也可以当作值来用:
ini
let student: { name: string, gender: GenderEnum } = {name: '张三',gender: GenderEnum.man,}
f、any 和 unknown
any 和 unknown 都可以用来表示任意类型的数据。
ini
let a: any = 1;
a = 'hello';
let b: unknown = 1;
b = 'hello';
let c: boolean = true;
c = a; // 不报错//
c = b; // 报错
any 和 unknown 的区别在于:
- any 类型的数据可以再次赋值给其他任意类型;unknown 类型的数据只能赋值给其他的 unknown 或 any;
- 数据一旦设置为 any 类型后,会关闭 TS 的类型检查;数据设置为 unknown 后,还是会进行类型检查。
g、void
void,当一个函数内部没有设置返回值时,返回值的类型就是 void:
ini
const foo = (): void => {}
h、never
never 用来表示永远都不会有值的数据的类型:
ini
const foo = (): never => {while(true) { }}
TS 中的函数可以像 JS 中一样的使用,但是 TS 中要求对函数进行类型约束:
- 约束参数的类型;
- 约束返回值的类型;
- 约束函数自身的类型;
三、TypeScript函数
1、基本语法
语法结构:
javascript
function 函数名(形参: 参数类型, 形参: 参数类型): 返回值类型 {
return 返回值;
}
函数名(数据, 数据);
示例代码:
javascript
方式一:
function foo(x: number, y: number): number {
return x + y;
};
foo(1, 2);//调用函数foo
方式二:【推荐】
const bar = (x: number, y: number): number => {
return x + y;
}
bar(10, 20);//调用函数bar
2、函数参数
a、参数默认值
javascript
function foo(x: number, y: number = 0): number {
return x + y;
};
foo(1, 2);
注意:带有默认值的参数通常放在所有形参的最后。
b、不定参数
javascript
const bar = (y: number, ...x: number[]) => {
}
bar(10, 20, 30, 40);
注意:不定参数通常放在所有形参的最后。
c、可选参数
javascript
function foo(x: number, y?: number) {
};
foo(1);
注意:可选参数通常放在所有形参的最后。
3、函数自身的类型约束
TS 是一个可选的静态的类型系统,可以用来约束变量 、函数的参数和返回值。仅需要在变量 、函数的参数和返回值位置加上" : 类型 "
-
变量
javascriptlet name:string;
-
函数
javascriptconst bar=(x: number,y: number)=>{ return x + y; } console.log(bar(1,2));
四、TypeScript高级类型
1、类型别名
类型别名的作用,就是对已经存在的类型进行重命名。
javascript
type bool = boolean; //为boolean类型取别名bool
let a: bool = true; //使用别名bool做为数据类型
通常,我们可以对一个对象的类型,进行别名配置
javascript
type StudentItem = { id: number, name: string, age?: number };
let a: StudentItem = {id: 1,name: '张三',}
2、联合类型
联合类型就是通过 |
来定义多个类型,数据只要匹配多个类型中的任意一个即可
javascript
let a: number | string | boolean = 'hello';
当数组中需要包含多个类型的数据时,就可以通过联合类型来设置数组内部数据的类型。
javascript
let a: (number | string)[] = [1, 2, 3, '4', '5']
联合类型和类型别名可以一起使用
javascript
type NumStr = number | string;
let a: NumStr[] = [1, 2, 3, '4', '5'];
let b: NumStr = 'hello';
3、交叉类型
交叉类型就是通过 &
来将多个类型合并成一个类型。
javascript
type Person = {id: number,name: string,age: number};
type Address = {province: string,city: string};
let student: Person & Address = {id: 1,name: '张三',age: 20,province:'四川',city: '成都'};
注意:交叉类型通常只能用来对象类型身上,将多个对象合并成一个对象。
交叉类型也可以和类型别名一起使用
javascript
type Person = {id: number,name: string,age: number};
type Address = {province: string,city: string,};
type StudentItem = Person & Address;
let student: StudentItem = {id: 1,name:'张三',age: 20,province:'四川',city:'成都'};
五、类型断言
类型断言是一种方式,可以手动指定变量的类型,非空断言是一种类型断言的特殊形式,
类型断言,指的是在某些特殊情况下,我们比 TS 更加确定数据的类型。因此,这种时候我们可以通过断言的方式来断定数据的类型。
1、基本语法
断言提供了两种语法:
<>
as
:推荐用 as
语法结构如下:
javascript
<类型>数据 as 类型
示例代码:
javascript
let arr: number[] = [1, 2, 3, 4]; //定义数组
//查找数组中>=2的元素,返回的值为number
const result = arr.find((item) => {
return item >= 2;
})
改为如下则会报错,因为ts不知道结果的类型
const result: number = arr.find((item) => {
return item >= 2;
})
上面的情况我们很确定结果的类型number但是ts无法确定,可以使用断言确定其返回值果就是number类型
const result: number=<number>arr.find((item)=>{
return item>=2
})
也可以写成如下形式
const result: number = arr.find((item) => {
return item >= 2;
}) as number;
2、非空断言
TS 中可以通过 !
来对数据进行非空断言,断定数据不会是 undefined 或 null。
语法结构:
javascript
数据!
示例代码:
javascript
const result: number = arr.find((item) => {
return item >= 2;
})!
六、接口 interface
1、接口和对象
接口,可以用来定义对象或函数的类型。
a、基本语法
-
语法
iniinterface 接口名 { 属性名: 数据类型; 属性名: 数据类型; }
-
示例 :
javascript//定义接口 interface StudentItem { id: number; name: string; age: number; } //将接口做为数据类型 const student: StudentItem = { id: 1, name: '张三', age: 20, }
b、可选属性
在接口中使用?修饰的属性在使用时可以不指定值
javascript
//定义接口
interface StudentItem {
id: number;
name: string;
age?: number;
}
//创建对象
const student: StudentItem = {
id: 1,
name: '张三',
}
c、只读属性
在接口中使用readonly 修饰的属性不能重新赋值
javascript
//定义接口
interface StudentItem {
readonly id: number; //id属性被设置为只读
name: string;
age: number;
}
//创建对象
const student: StudentItem = {
id: 1,
name: '张三',
age: 20,
}
//改变对象中属性的值
student.id = 2; // 报错
2、接口和函数
javascript
语法:
interface 接口名 {
属性名: 数据类型;
属性名: 数据类型;
}
示例:
interface BarFn {
(x: number, y: number): number
}
const bar: BarFn = (x, y) => {
return x + y;
}
bar(1, 2);
3、接口和接口
在一个接口中,可以去使用另一个接口,同理,也可以使用当前接口自身。
javascript
interface MenuItem {
id: number,
title: string,
children?: MenuItem[]
}
const menusData: MenuItem[] = [
{
id: 1,
title: '首页'
},
{
id: 2,
title: '用户管理',
children: [
{
id: 3,
title: '用户列表'
},
{
id: 4,
title: '用户分组'
}
]
}
]