TS快速上手

1. TS简介

TS属于 JS 的超集,支持所有的 JS 的语法,然后新增了其他内容,比如类型约束,接口,泛型,枚举等等。

2. TS环境搭建

npm i -g typescript

编译:tsc index.ts

3. TS语法

3.1 类型约束

概述:在ts中生命的变量(或者函数的参数等)都会进行类型约束,不同类型的数据之间不能赋值。

1. 字符串类型

1
2
let str:string = 'abc'
str = ='123'

2. 数值类型

1
let num:number = 123

3. 布尔值类型

1
let bool:boolean = true

4. symbol类型

1
let sy:symbol = Symbol()

5. null和undefined类型

6. any 类型

该类型可以被赋予任何类型的值

7. void类型

没有任何类型,在函数没有返回值的时候使用

1
2
3
function foo():void {
console.log()
}

8. never

永远不会存在值得类型

9. unknown

10. 元组类型(Turple)

概述:用于定义具有有限数量的未命名属性的类型,适用元组时必须提供每个属性的值。

1
2
3
4
5
6
7
let tu:[string,number] = ['abc',123]

// 访问
tu[0]

// push 不会报错但是push不进去
tu.push(123)

11. 枚举类型(enum)

概述:用于组织收集一组相关变量的方式,可以非常清晰的去表达意图

作用:给数值或其他数据进行语义化,提高代码的可读性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 数字枚举
enum Color {
Red, // Color.Red表示0
Green,// Color.Green表示1
Blue,//Color.Blue表示2
Yellow// Color.Yellow表示3
}

// 设置初始值
enum Color {
Red = 1, // Color.Red 表示 1
Green, // Color.Green 表示 2
Blue, // Color.Blue 表示 3
Yellow // Color.Yellow 表示 4
}

// 字符串枚举 所有枚举成员都必须给初始值
enmu Role {
Admin = 'admin',
User = 'user'
}

// 字符串枚举和数值枚举混合
enum Hun {
A, // 0
B, // 1
C = 'c',
D = 'd',
E = 6, // 在字符串枚举之后的数值必须给初始值
F // 7
}

12. 接口

概述:接口是对行为抽象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// 语法
interface 接口名 {
属性:属性类型
}

// 约束对象
interface Props {
path:string;
name:string
}
const obj:Props = {
path:'/login',
name:'login'
}

// 约束数组
interface Props {
[key:number]:string
}
const obj:Props = ['a','b','c']

// 对象方法的约束
interface Props {
path:string;
name:string;
foo:()=>void; // foo 是一个方法,没有返回值,没有参数
}
const objLProps = {
path:'/login',
name:'login',
foo() {}
}

// 可选属性
interface Props {
path: string;
name: string;
title?: string;
}

// 只读属性
interface Props {
path: string;
name: string;
readonly title: string;
}

// 任意属性
interface Props {
path: string;
name: string;
[key: string]: any;
}

// 接口继承
interface PropsA {
path: string;
}

interface PropsB extends PropsA {
name: string;
}
const obj: PropsB = {
path: '',
name: ''
}

13. 类型别名

概述:用于给一个类型去一个新的名字,和接口有点类似,可以用于原始类型、接口联合等等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Name = string;
type Name = string | null; // 联合类型,或者,两个类型之一
type Foo = () => string; // 约束函数,没有参数,返回值是 string
type Resolve = Name | Foo;
type IProps = {
url: string;
foo: () => void;
}

// 交叉类型
interface IPA {
x: number;
}
interface IPB {
y: number;
}

type IP = IPA & IPB;

14. 函数类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function foo(x: number, y: number): number {
return x + y;
}

const foo: (x: number, y: number) => number = function (x: number, y: number): number {}

// 简写
const foo: (x: number, y: number) => number = function(x, y) {}

// 结合 type
type FnProps = (x: number, y: number) => number;
const foo: FnProps = function(x, y) {}

// 可选参数
function foo(x: number, y: number, z?: number): number {
return x + y;
}

// 参数默认值
function foo(x: number = 0, y: number = 0): number {
return x + y;
}

15. 数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 约束数组方式1
const arr: string[] = ['a', 'b'];

// 约束数组方式2
const arr: Array<string> = ['a', 'b'];

// 约束数组方式3
interface AP {
[key: number]: string;
}
const arr: AP = ['a', 'b'];

// 复杂数组
interface IProps {
name: string;
path: string;
}
const arr: IProps[] = [{
name: '',
path: ''
}];

3.2 运算符

1. 非空断言 !

概述:一般用在变量名或者函数名之后,用于强调对应的元素时null 或者 undefined

1
2
3
function foo (callback?: ()=?void) {
callback!()
}

2. 链运算符 ?

概述:用来判断左侧的表达式是否为null 或者 undefined ,如果为空就不执行,否则执行后面的代码。

a?.b()

类似

success && success()

3. 类型断言

概述:我确定的知道某个变量的类型

1
2
3
4
5
6
function isFish(animal: Cat | Fish) {
if (typeof (animal as Fish).swim === "function") {
return true;
}
return false;
}

3.3 class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Person {
name: string; // 默认公开属性
public age: number; // public 表示公开属性
private height: number = 160; // private 私有属性,只能在类的内部使用,子类和实例都不能使用
protected city: string = "成都"; // protected 受保护的,可以在子类中访问,但是实例不能访问

static version = "v1"; // 静态属性,只能通过类名调用
constructor(name: string, age: number) {
// 构造函数
this.name = name; // name 是加在实例上的
this.age = age;
}

sayHi() {
console.log(this.height);
}

get birth() {
// get 方法
return 1990 + this.age;
}
set birth(a: number) {
// set 方法
this.age = a;
}
}

// 继承
class Student extends Person {
constructor(name: string, age: number) {
super(name, age);
}
}

// 抽象类 - 只能被继承,不能被实例化,一般用于抽取类中的公共代码
abstract class Animal { }

class Cat extends Animal { }

new Cat();

// 类也可以继承接口
interface PersonProps {
name: string;
}

class Admin implements PersonProps {
name: string = "admin";
}

3.4 泛型

概述:泛型是指在定义函数、接口或者类的时候,不预先制定具体的类型,而是在使用的时候在指定类型的一种特性。简单理解就是给类型变成一个变量。

定义: 泛型使用 <> 进行定义,使用 A - Z 来定义泛型变量,常见的为 T, K, U

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function id(value: number): number {
return value;
}
id(123);

function idS(value: string): string {
return value;
}
idS('abc');

function idA(value: any): any {
return value;
}

// 优化,使用一个 T 去表示一个类型
function id<T>(value: T): T {
return value;
}
// 使用的时候在指定类型
id<number>(1);

id<string>('abc');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>> 其他泛型定义
function foo<T, U>(x: T, y: U): void {
// ...
}

foo<string, number>('abc', 123);

function foo<T>(arg: Array<T>) {}

interface Props<T> {
name: string;
children: T;
}

class Cat<T = any> { // 泛型默认值
type: T;
constructor(type: T) {
this.type = type;
}
}

// 泛型继承
function foo<T extends Date>(arg: T) {}