typescript笔记
# 1. 构建typescript工程化开发环境
# 1-1. 创建目录结构如下
创建一个项目目录结构如下:
ts_webpack
|- src
| |-index.ts
|-public
| |-index.html
|-webpack.config.js
1
2
3
4
5
6
7
2
3
4
5
6
7
- src/index.ts
let str:string = 'abc'
console.log(str);
1
2
2
- public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- webpack.config.js
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.ts',
output: {
path: resolve(__dirname, 'build'),
filename: 'js/bundle.js'
},
mode: 'development',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader'
}
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
inject:'body'
})
],
devServer: {
port: 5000,
open: true
}
}
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
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
# 1-2. 创建 package.json
# 命令终端目录在 ts_webpack中执行
npm init -y
1
2
2
# 1-3. 安装相关依赖
npm i webpack webpack-cli webpack-dev-server ts-loader html-webpack-plugin typescript -D
1
# 1-4. 创建 tsconfig.js
# 命令终端目录在 ts_webpack中执行
tsc --init
1
2
2
# 1-5. 运行项目
npx webpack-dev-server
1
# 2. 基本数据类型
// 1. boolean
let b1:boolean = true;
b1 = false;
// b1 = 123; // 报错:不能将类型“number”分配给类型“boolean”
// 2. number
let num1:number = 123;
num1 = 1.3;
num1 = -20;
num1 = 0;
num1 = NaN;
// num1 = 'abc'; // 报错: 不能将类型“string”分配给类型“number”
// 3. string
let str:string = 'abc';
str = 'zyx'
// str = 123; // 报错:不能将类型“number”分配给类型“string”。
// 4. object 引用类型 【了解】
let obj1:object = {name:'atguigu', age:20};
obj1 = [1,2,3];
obj1 = function(){
console.log(123);
}
// 5. 数组:
let arr:number[] = [1,2,3];// arr是一个元素都是数字的数组
// 泛型方式
let arr2:Array<number> = [20,30,40];
let arr3:string[] = ['1','2','3']
let arr4:Array<string> = ['a','b','c']
// 6. any 任意类型: 能不用就不用
let a:any = 123;
a = 'abc';
a = true;
a = [1,2,3];
// 7. void: 限制为 undefined, 一般用来限制函数的返回值
function fn(a:number,b:number):void{
console.log(a,b);
}
// 8. tuple 元组:元组就是一个特殊的数组,长度以及数组每一个元素的类型已经确定了
let t1:[number, string] = [10,'jame'];
// 9. 枚举 enum
let sex = 1; // sex 0 sex 2
// man woman secret
// male female
if(sex === 1){
}else{
}
// 以下代码, left 表示右, right 表示左
// let v1 ... v12
enum gender {
man,
woman=100,
secret
}
if(sex === gender.woman){
}
console.log(gender);
// 联合类型
let x:number|string = 123;
x = 'abc';
function getX(x:number|string){
console.log(x.toString());// 联合类型必须使用都有的属性,才不会报错
// 使用一个有,其他没有的会报错,怎么解决呢? 使用类型断言
if((x as string).length){ // 说明是字符串
}else{// 说明是数字
}
}
// x = true; // 报错: 不能将类型“boolean”分配给类型“string | number”
// 类型断言:
let oDiv = document.querySelector('#root') as HTMLElement
// const root = ReactDOM.createRoot(document.querySelector('#root') as HTMLElement)
// 类型推断: 如果不指定类型,那么首次赋值的类型就是该变量的类型
let num99 = 123;
// num99 = 'abc';// 报错:不能将类型“string”分配给类型“number”
export {}
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# 3. 函数
- 定义:
- 字面量
- 完整写法
- 简写【类型推断】
- 声明式定义
- 参数
- 可选参数
- 参数默认值
- 剩余参数
# 4. 类
- ts中的类比ES6中的类多了参数类型限定及 属性声明
- 类的继承
- 访问修饰符 public protected private
class Person{
// 私有属性类型声明
name:string;
age:number;
constructor(name:string, age:number){
this.name = name;
this.age = age;
}
say():void{
console.log(this.name, this.age);
}
}
let p1 = new Person('yuonly', 19)
console.log(p1);
p1.say();
// 2. 继承
class Programmer extends Person{
skill:string;
constructor(name:string, age:number, skill:string){
super(name, age);
this.skill = skill
}
info():void{
console.log(this.name, this.age, this.skill);
}
}
let pro1 = new Programmer('巩开拓', 30, 'javascript');
console.log(pro1);
pro1.info();
/**
成员修饰符
类内部 继承子类 类外部
public[公开的] y y y
protected[受保护的] y y n
private[私有的] y n n
*
*/
class Father{
public name:string;
protected money:number;
private secret:string;
constructor(name:string, money:number, secret:string){
this.name = name;
this.money = money;
this.secret = secret;
}
say():void{
console.log('public: ', this.name);
console.log('protected: ', this.money);
console.log('private: ', this.secret);
}
}
class Son extends Father{
constructor(name:string, money:number, secret:string){
super(name, money, secret);
}
hello():void{
console.log('public name: ', this.name);
console.log('protected money: ', this.money);
// console.log('private secret: ', this.secret); // 报错,私有属性子类无法访问
}
}
let s1 = new Son('s', 20, '我觉得开发');
console.log(s1.name);
// console.log(s1.money);
// console.log(s1.secret);
export {}
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 5. 接口
接口作用:对对象的属性和方法的类型进行限定
语法:
interface IPerson{ readonly id:string; // 只读 name:string; age:number; sex?:string; // 可选 cook():void; // 接口限定方法,方式一 cook:()=>void; // 接口限定方法,方式二 }1
2
3
4
5
6
7
8接口限定类:
类实现一个接口,那么就要有该接口定义的所有的属性和方法
class 类 implements 接口{ }1
2
3类可以实现多个接口,这个类就要有所有这些接口定义的属性和方法
class 类 implements 接口1,接口2,...{ }1
2
3接口可以继承
interface 接口1 extends 接口2,接口3{ }1
2
3重复定义接口: 同名的接口可以重复定义,重复定义的属性和方法,都会成为该接口的限定
interface ICar{ name:string; } interface ICar{ age:number; } let c1:ICar = { name:'poerche', age:20 }1
2
3
4
5
6
7
8
9
10
11
12
# 6. 泛型
可以传递类型的参数,称之泛型参数
要求都是 大写字母:K、T、V、P、S、R为泛型
- 泛型接口
- 泛型类
- 泛型约束
/**
* 泛型:可以传递类型的参数,成为泛型
*
* 泛型参数,要求都是 大写字母:K、T、V、P、S、R
*/
function createArr<K>(num: number, item: K): K[] {
let arr: K[] = [];
for (let i = 0; i < num; i++) {
arr[i] = item;
}
return arr;
}
console.log(createArr<string>(3, 'a')); // ['a','a','a']
console.log(createArr<number>(2, 99)); // [99,99]
// 泛型参数可以不止一个
function createArray<T, P>(a: T, b: P): [T, P] {
return [a, b]
}
console.log(createArray<number, string>(1, 'abc'))
// 泛型接口
interface IResponse<T> {
code: number;
msg: string;
data: T
}
interface IBook {
id: string;
name: string;
author: string;
}
interface ITodo {
id: string;
title: string;
isDone: boolean;
}
let data1: IResponse<IBook> = {
code: 200,
msg: '成功',
data: {
id: 'adfd123',
name: '葵花宝典',
author: '东方不败'
}
}
let data2: IResponse<ITodo> = {
code: 200,
msg: '获取数据成功',
data: {
id: '123',
title: '吃饭',
isDone: true
}
}
// 泛型类:用泛型限定类
class Container<T>{
//用于储存数据
store: T[];
constructor(store: T[]) {
this.store = store;
}
}
let books = new Container<IBook>([
{ id: 'ab123', name: '西游记', author: '吴承恩' },
{ id: 'sx23', name: '三国演义', author: '罗贯中' }
])
let todos = new Container<ITodo>([
{ id: 'sfre1', title: 'chifan', isDone: true }
])
// 泛型约束
// function fn<T>(x: T): void {
// // console.log(x.length) // error
// }
// fn(2);
// fn(true);
// fn([1,2,3]);
// fn('abc');
interface Lengthwise {
length: number;
}
// 指定泛型约束
/**
* 泛型是一种特殊类型的接口
*/
function fn2<T extends Lengthwise>(x: T): void {
console.log(x.length)
}
fn2('abc')
// fn2(123);
fn2([1,2,3])
export { }
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# 7. 类型声明
使用type关键字可以进行自定义类型的声明
/**
* 我们可以使用 type 关键字,自己定义一些类型
*
*/
type ns = number | string;
let a: ns = 123;
a = 'abc';
interface IUserItem {
login: string;
id: number;
avatar_url: string;
html_url: string;
}
type IUserList = IUserItem[]
interface IResponse {
total_count:number;
incomplete_results:boolean;
items:IUserList
}
export { }
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 8. 声明文件
/**
* 在项目中会使用第三方的库, ts是在编译阶段进行语法检查,导入第三方库的函数或对象,本身不是js的变量,ts不认识他们
* axios
*
* 在ts项目中,使用 npm i 包
* 同时也会将该包的声明文件安装成功,如果没有安装成功声明文件,
* 1. 需要单独安装 npm i @types/包名
* npm i @reduxjs/toolkit npm i @types/@reduxjs__toolkit
*
* 2. 自定义声明文件, 该文件是在根目下,以 xxxx.d.ts结尾的文件
*
* 导致安装包,不能自动安装声明文件导致报错的原因及解决方案:
* 1. 当前 npm 的镜像源没有该声明文件
* 重新设置其他的源,设置官方源
*
* 2. 网速不好下载不下来:手动重新安装,或者删除node_modules目录,重新执行 npm i
*/
// $('body').css('background','#aef');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 9. 内置类型
// boolean 是 内置类 Boolean 子类型
let b1: Boolean = true;
console.log(b1);
// let b2:boolean = new Boolean(2); // boolean 和 Boolean不是一个类型
// 包装对象
let num: number = 123;
console.log(num.toString()); // let t = new Number(123) t.toString()
// Bom Dom 内置对象
const div: HTMLElement = document.getElementById('test') as HTMLElement
const divs: NodeList = document.querySelectorAll('div')
document.addEventListener('click', (event: MouseEvent) => {
console.dir(event.target)
})
// const root = reactDOM.createRoot(document.getElementById('root') as HTMLElement)
export { }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
编辑 (opens new window)