TypeScript 是 javaScript 的类型的超集,它可以编译成纯 javaScript。编译出来的 javaScript 可以运行在任何浏览器上。TypeScript 编译工具可以运行在任何服务器和任何系统上。TypeScript 是开源的。
首先声明一点:TypeScript 中变量是强类型的。
TypeScript 中为了使编写的代码更加规范,更有利于维护,增加了类型校验,就是在定义变量的时候要指定变量类型。
TypeScript 中的数据类型(12 种)有:
- undefined
- null: 空类型;
- Number: 数值类型;
- String: 字符串类型;
- Boolean: 布尔类型;
- Object
- enum: 枚举类型;
- any: 任意类型;
- void: 空类型;
- Array: 数组类型;
- Tuple: 元组类型;
- never 类型
ts 代码必须指定变量类型。
数组(引用类型)
声明数组的方法(两种)
// var arr = [1, 2, 3]; // es5定义数组方式
// ts定义数组,方式1,声明一个数值类型的数组
let arr: number[] = [1, 2, 3];
console.log(arr);
// ts定义数组,方式2,声明一个字符串类型的数组
let arr2: Array<string> = ['2', '3', '4'];
console.log(arr2);
2
3
4
5
6
7
8
给数组赋值
- 字面量赋值法
- 构造函数赋值法
// 字面量赋值法
const arr1: number[] = []; // 定义一个空数组
const arr2: number[] = [1, 2, 3]; // 定义一个只能存放数值类型的数组
const arr3: Array<string> = ['a', 'b'];
const arr4: Array<boolean> = [true, false];
2
3
4
5
6
需要注意的是:在 TypeScript 中指定数据类型的数组只能存储同一类型的数组元素。
// 报错,必须存储number类型的数据
const arr: number[] = [1, 2, true];
2
在 TypeScript 中使用 Array 这个引用类型来表示数组的,那么每一个数组都是 Array 类型的实例。那么,我们在创建数组的时候也可以使用构造函数来进行赋值。
// 构造函数赋值法
let arr1: number[] = new Array();
let ara2: number[] = new Array(1, 2, 3, 4, 5);
let arr3: Array<string> = new Array('a', 'b', 'c');
let arr4: Array<boolean> = new Array(true, false);
2
3
4
5
元组(属于数组的一种)
元组(开发中用的比较少)是一种特殊的数组,可以给数组中的每个索引元素指定数据类型。元祖类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
// 初始化正确(数组的第一个元素必须是数字,第二个元素必须是字符串,第三个元素必须是布尔值)
const tuple: [number, string, boolean] = [24, 'abc', true];
2
// 初始化失败
const tuple: [number, string, boolean] = ['24', 'abc', true];
2
如果不遵循为元组预设排序的索引规则,那么 Typescript 会警告: tuple 第一项应为 number 类型。
字符串(String)
在 TypeScript 中存在两种类型的字符串:
- 基本类型字符串:由单引号或者双引号括起来的一串字符串。
- 引用类型字符串:用 new 实例化的 String 类型。
const str1: string = '123';
const str2: String = new String('test');
console.log(str1); // '123'
console.log(str2); // [String: 'test']
console.log(str1.length); // 3
console.log(str2.length); // 4
2
3
4
5
6
需要说明的是:这两种声明字符串的方法没有什么不同。基本类型的字符串可以直接使用引用类型的属性和方法。
日期对象(引用类型)
不传递任何参数
const d: Date = new Date();
console.log(d); // 2020-02-02T09:50:43.484Z
2
传递一个整数
传递一个整数,这个整数代表的是距离 1970-01-01 00:00:00 的毫秒数(具体为什么是这个时间,小伙伴可以自己百度一下)。例如:传入参数为 1000,将创建一个表示 1970-01-01 00:00:01 的日期对象。
我们举个例子,传递一个整数,看一下结果:
const d2: Date = new Date(1000);
const d3: Date = new Date(2000);
console.log(d2); // 1970-01-01T00:00:01.000Z
console.log(d3); // 1970-01-01T00:00:02.000Z
2
3
4
传递一个字符串
如果传递一个表示日期的字符串,就会生成相对应的日期对象。字符串的格式常用:yyyy/MM/dd hh:mm:ss,yyyy-MM-dd hh:mm:ss,yyyy-MM-ddThh:mm:ss 等,具体可以参看下面的例子:
const d4: Date = new Date('2020/02/02 05:55:00');
const d5: Date = new Date('2020-02-02 05:55:00');
const d6: Date = new Date('2020-02-02T05:55:00');
console.log(d4); // 2020-02-01T21:55:00.000Z
console.log(d5); // 2020-02-01T21:55:00.000Z
console.log(d6); // 2020-02-01T21:55:00.000Z
2
3
4
5
6
传递表示年月日时分秒的变量
let d: Date = new Date(year, month, day, hours, minutes, seconds, ms);
- year:表示年份,4 位数字;
- month:表示月份,数值是 0(1 月)~11(12 月)之间的整数。
- day:表示日期。数值是 1~31 之间的整数。
- hours:表示小时,数值是 0-23 之间的整数。
- minutes:表示分钟数,数值是 0~59 之间的整数。
- seconds:表示秒数,数值是 0~59 之间的整数。
- ms:表示毫秒数,数值是 0~999 之间的整数。
正则表达式
创建正则表达式的两种方法:
- 构造函数法
- 字面量法
构造函数法
构造函数中可以传一个参数,也可以传递两个参数。一个是字符串描述,另一个是修饰符,比如 g 是全局修饰符,i 是忽略大小写,m 是多行模式。
const reg1: RegExp = new RegExp('testreg');
console.log(reg1); // /testreg
const reg2: RegExp = new RegExp('testreg', 'gi');
console.log(reg2); // /testreg/gi
2
3
4
字面量法
其实构造函数的方法我个人用的是比较少的,我都会使用字面量法来声明正则表达式。
let reg3: RegExp = /testreg/;
let reg4: RegExp = /testreg/gi;
2
RegExp 中的常用方法
RegExp 对象包含两个方法:test 和 exec,功能基本相似,用于测试字符串匹配。
- test(string):在字符串中查找是否存在指定的正则表达式并返回布尔值,如果存在则返回 true,不存在则返回 false。
- exec(string):用于在字符串中查找指定正则表达式,如果 exec()方法执行成功,则返回包含该查找字符串的相关信息数组。如果执行失败,则返回 null。
const reg1: RegExp = new RegExp('testreg');
console.log(reg1); // /testreg
const stra: string = 'testreg.com';
const res: boolean = reg1.test(stra);
console.log(res);
2
3
4
5
const stra: string = 'testreg.com';
const reg2: RegExp = new RegExp('testreg', 'gi');
const res2: any = reg1.exec(stra);
console.log(res2); // [ 'testreg', index: 0, input: 'testreg.com' ]
console.log(reg2); // /testreg/gi
2
3
4
5
enum(枚举)
定义格式如下:
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
}
2
3
4
5
6
特别说明:如果标识符没有赋值,其值就是对应标识符的下标。如果赋值了,就是对应的初始值。
// 枚举类型
enum Roles {
SUPER_ADMIN = 1, // 赋值初始值
ADMIN = 4,
USER
}
// 获取到的是索引值
console.log(Roles.SUPER_ADMIN); // 1
// 也可以根据索引值获取到对应的枚举属性值
console.log(Roles[4]); // 'ADMIN'
// 标识符的值是递增的
console.log(Roles.USER); // 5
2
3
4
5
6
7
8
9
10
11
12
13
enum SEX {man, woman, yao};
console.log(SEX.woman); // 这里返回1,是索引index值,跟数组很像
2
// 可以使用=给枚举赋值
enum SEX {
man = '男人',
woman = '女人',
yao = '妖'
};
console.log(SEX.woman); // 女人
2
3
4
5
6
7
enum Flag {
succuss = 1,
error = 2,
undedined = -1,
null = -2
}
// 指定s和e均为枚举类型
let s:Flag = Flag.succuss;
let e:Flag = Flag.error;
let u:Flag = Flag.undedined;
let n:Flag = Flag.null;
console.log(s, e, u, n); // 1 2 -1 -2
2
3
4
5
6
7
8
9
10
11
12
// 枚举
// 默认情况从0开始为元素编号,也可手动为1开始
enum Color {Red=1, Green, Blue}
let c:Color = Color.Blue;
console.log(c); // 3
let colorName:string = Color[2];
console.log(colorName); // Green 因为上面代码里它的值是2
2
3
4
5
6
7
any
基本用法
// 相当于es5中的没有类型校验
let anytest: any = 123;
anytest = 'test';
console.log(anytest);
2
3
4
5
any 类型的使用场景
const box: any = document.querySelector('.box');
box.style.color = 'red';
2
在 ts 中不设置 any 会报错:
null 和 undefined
null 和 undefined 是其他(never 类型)数据类型的子类型。
undefined
// 设置a是undefined类型
let a: undefined;
console.log(a); // 正确
2
3
// 设置a是null类型
let a: null;
a = 123; // 报错,只能赋值为null
2
3
let a: number;
console.log(a); // 报错
2
// num2为null、undefined或者数值类型
// 给一个元素设置多个类型
var num2: number | undefined | null;
num2 = 123;
console.log(num);
2
3
4
5
void
void 类型表示没有任何类型,一般用于定义没有返回值的方法。
// 表示run方法没有返回值
function run(): void {
console.log(111);
}
// 指定为undefined表示该方法返回undefined
function run(): undefined {
console.log(111);
// 定义返回值为undefined,必须显式返回undefined
return undefined;
}
2
3
4
5
6
7
8
9
10
// void类型
const fn = (str: string): void => {
console.log(str);
// 默认返回undefined
};
fn('test');
let kong: void;
kong = undefined;
// kong = null; // 报错,不能将null赋值给void类型
2
3
4
5
6
7
8
9
never
never 类型:即其他类型(包括 null 和 unfined)的子类型,代表从不会出现的值。never 类型的变量只能被 never 类型赋值。
let a: undefined;
a = undefined;
let b: null;
b = null;
let c: never;
c = (() => {
throw new Error('错误');
})();
2
3
4
5
6
7
8
9
10
const errorFunc = (msg: string): never => {
// 定义返回值是never类型
throw new Error(msg);
};
const infiniteFunc = (): never => {
// 死循环
while (true) {}
};
2
3
4
5
6
7
8
上述两种情况:抛出错误和死循环都不会有返回值,因此可以指定返回值是 never 类型。
Object 类型
const func = (obj: object): string => {
return `${obj}`;
};
func({ name: 'lisi' });
2
3
4
类型推论(类型断言)
如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。
如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查。
const getLength = (target:string | number):number => {
if ((<string>target).length || (target as string).length === 0) {
return (target as string).length;
} else {
return target.toString().length;
}
}
2
3
4
5
6
7
类型断言的两种写法:断言 target 为 string 类型。
(<string>target)
- (target as string)
联合类型
联合类型(Union Types)表示取值可以为多种类型中的一种。
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
2
3
let myFavoriteNumber: string | number;
myFavoriteNumber = true;
// index.ts(2,1): error TS2322: Type 'boolean' is not assignable to type 'string | number'.
// Type 'boolean' is not assignable to type 'number'.
2
3
4
5
联合类型使用 | 分隔每个类型。这里的let myFavoriteNumber: string | number
的含义是,允许 myFavoriteNumber 的类型是 string 或者 number,但是不能是其他类型。
访问联合类型的属性或方法
当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:
function getLength(something: string | number): number {
return something.length;
}
// index.ts(2,22): error TS2339: Property 'length' does not exist on type 'string | number'.
// Property 'length' does not exist on type 'number'.
2
3
4
5
6
上例中,length 不是 string 和 number 的共有属性,所以会报错。 访问 string 和 number 的共有属性是没问题的:
function getString(something: string | number): string {
return something.toString();
}
2
3
联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型:
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
console.log(myFavoriteNumber.length); // 5
myFavoriteNumber = 7;
console.log(myFavoriteNumber.length); // 编译时报错
// index.ts(5,30): error TS2339: Property 'length' does not exist on type 'number'.
2
3
4
5
6
7
上例中,第二行的 myFavoriteNumber 被推断成了 string,访问它的 length 属性不会报错。 而第四行的 myFavoriteNumber 被推断成了 number,访问它的 length 属性时就报错了。