typescript学习
TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持
# 什么是 TypeScript
TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open source. TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。TypeScript 编译工具可以运行在任何服务器和任何系统上。TypeScript 是开源的。
ts 简易教程-传送门 (opens new window)
# ts 脑图
![](/blog/assets/img/naotu.6b5da0e9.jpeg)
# 类型
在 typescript 中,类型可以分为基本类型和枚举类型
# 基本类型
- 数字类型(number)
- 字符串类型(string)
- 布尔类型(boolean)
- 数组类型(array)
- 元组类型(tuple)
- 函数类型(fuction)
- 对象类型 (object)
- symbol 类型
- void 类型
- any 类型
- null 和 undefined
- never 类型
# 数字类型
和 JavaScript 一样,TypeScript 里的所有数字都是浮点数。 这些浮点数的类型是 number。 除了支持十进制和十六进制字面量,TypeScript 还支持 ECMAScript 2015 中引入的二进制和八进制字面量。
let num: number = 123;
num = 0b1101; // 二进制
num = 0o164; // 八进制
num = 0x8b; // 十六进制
2
3
4
# 字符串类型
和 JavaScript 一样,可以使用双引号(")或单引号(')表示字符串。
let str: string = "wjs";
# 布尔类型
let bool: boolean = true;
# 数组类型
有两种方式可以定义数组。 第一种,可以在元素类型后面接上[],表示由此类型元素组成的一个数组
let arr: number[] = [1, 2, 3];
let arr: string[] = ["1", "2", "3"];
let arr: (string | number)[] = [1, "2", 3]; // 数组中元素只能为string或者number类型
let arr: any[] = [1, "2", true]; // 数组中的元素为任意类型
2
3
4
第二种方式是使用数组泛型,Array<元素类型>:
let arr: Array<number> = [1, 2, 3];
let arr: Array<number | string> = [1, "2", "3"];
let arr: Array<any> = [1, "2", true];
2
3
# 元组
数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。
元组中允许存储不同类型的元素,元组可以作为参数传递给函数。
let x: [string, number];
x = ["123", 123];
x = [123, "123"]; // error
或者;
let x: [string, number] = ["123", 123];
2
3
4
5
6
7
其它的操作方法和数组一致
# fuction
let func = (param?: type): type {};
# object
let obj: { param: type } = { param: typeValue };
# symbol
let sym: symbol = Symbol();
# 空值 void
void 类型像是与 any 类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void
let a = (): void => {
console.log("xxx");
};
2
3
声明一个 void 类型的变量没有什么大用,因为你只能为它赋予 undefined 和 null;
let v: void;
v = undefined; // OK
2
# any
any 表示当前变量可能是任何类型
let a: any = "123";
a = true;
a = [1, 23, 4];
2
3
尽量少的使用 any, 否则你可能在用 AnyScript 写代码
# null 和 undefined
TypeScript 里,undefined 和 null 两者各自有自己的类型分别叫做 undefined 和 null, 是 string 的子类型
let n:null = null;
let u:undefined: undefined;
2
# never
never 表示永不存在的值,出现在死循环或者异常程序中
function getError(message: string): never {
throw new Error(message);
}
function infiniteFunc(): never {
while (true) {}
}
2
3
4
5
6
# 枚举类型
- 数字枚举
- 字符串枚举
- 异构枚举
- 枚举成员
- 常量枚举
- 枚举/枚举成员作为类型
# 数字枚举
没有初始化值,默认从 0 开始自增
enum Role {
a,
b,
c,
}
// Role.a === 0;
// Role.c === 2;
2
3
4
5
6
7
当其中枚举成员赋值时,如果有枚举成员有数字初始化,则其后的成员会自动加一
enum Role {
a,
b = 5,
c,
}
// Role.a === 0;
// Role.b === 5;
// Role.c === 6;
2
3
4
5
6
7
8
当枚举成员有字符串初始化,其后的成员必须为字符串初始化
enum Role {
a,
b = "5",
// c = 3; // 枚举成员必须具有初始化表达式
c = "wjs",
}
// Role.a === 0;
// Role.b === 5;
// Role.c === 'wjs';
2
3
4
5
6
7
8
9
# 字符串枚举
在一个字符串枚举里,每个成员都必须用字符串字面量
enum Role {
SUPER = "超级管理员",
ADMIN = "管理员",
USER = "用户",
}
2
3
4
5
# 异构枚举
枚举可以混合字符串和数字成员
enum Answer {
N,
Y = "yes",
}
2
3
4
除非你真的想要利用 JavaScript 运行时的行为,否则我们不建议这样做。
# 枚举成员
- 枚举成员是只读的,不可以被后续更改
- 常量枚举在编译时被计算,非常量表达式,在运行时才会被计算
- 常量枚举,在编译后被移除
# 常量枚举
特性:会在编译阶段被移除 作用:当我们不需要一个对象,而需要这个对象的值时,就需要使用常量枚举,这样减少在编译环境的代码
const enum Month {
Jan,
Feb,
Mar,
}
const month: number[] = [Month.Jan, Month.Feb, Month];
2
3
4
5
6
# 枚举类型
在某些情况下,枚举和枚举成员都可以作为一种单独类型存在。 第一种情况,枚举成员没有任何初始值; 第二种情况,所有成员都是数字枚举; 第三种情况,所有成员都是字符串枚举。
enum E {
a,
b,
}
enum F {
a = 0,
b = 1,
}
enum G {
a = "apple",
b = "banana",
}
2
3
4
5
6
7
8
9
10
11
12
# 类型断言
类型断言就是手动指定一个类型的值
类型断言有两种形式。 其一是“尖括号”语法
let str: any = "this is a string";
let strLength: number = (<string>str).length;
2
另一个使用as语法
let str: any = "this is a string";
let strLength: number = (str as string).length;
2
# 接口
接口是一个抽象类型,是抽象属性和方法的集合,用来规范对象、方法和类的行为
# 对象类型
对象的属性包含可选属性和只读属性,只读属性不允许被赋值
interface obj {
name: string;
age?: number;
readonly sex: number;
}
let obj: obj = {
name: "wjs",
age: 25,
sex: 1,
};
// obj.sex = 0; // 无法分配到age, 因为它是只读属性
2
3
4
5
6
7
8
9
10
11
12
# 可索引接口
可索引的接口类型分为字符索引和数字索引,数字索引相当于数组,当两者混用时,数字签名的返回值必须是字符索引签名返回值的子类型
# 数字索引
interface obj {
[index: number]: number
}
let obj:obj {
0:1,
1:2,
4:3
}
2
3
4
5
6
7
8
# 字符串索引
interface obj {
[x: string]: string | number
}
let obj:obj {
'a': 0,
'b': 'wjs'
}
2
3
4
5
6
7
8
# 字符串和数字索引混用
interface obj {
[index: number]: number,
[x: string]: string | number
}
let obj:obj {
0: 1,
'a': 1,
'b': 'wjs'
}
2
3
4
5
6
7
8
9
10
# 函数类型接口
接口不仅可以定义对象的形式,还可以定义函数形式
interface F {
(name: string, age: number): void;
}
let f: F = (name, age) => {
console.log(name, age);
};
f("wjs", 25);
2
3
4
5
6
7
8
# 混合类型接口
一个对象既可以拥有属性,又可以拥有方法
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
fuction getCounter(): Counter {
let counter = <Counter>function (start: number) { };
// 或者写成这样 let counter = function (start: number) { } as Counter;
counter.interval = 123;
counter.reset = function () { };
return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 类类型接口
- 类必须实现接口中定义的所有属性
- 接口只能约束类的公有成员,不能约束私有成员,受保护成员,静态成员及构造函数
# 接口继承
接口也可以实现继承,使用关键字 extends实现,通过继承可以抽离可重用的接口,将多个接口合并成一个接口
interface Fruit {
name: string;
}
interface Apple extends Fruit {
color: string;
}
let apple: Apple = {
color: "red",
name: "apple",
};
console.log(apple.color); // red
console.log(apple.name); // apple
2
3
4
5
6
7
8
9
10
11
12
13
14
15