TypeScript看完就会了
TypeScript
什么是TypeScript?
TypeScript是由微軟開發的一款開源的編程語言
TypeScript是JavaScript的超集,遵循最新的ES5 ES6規范,TypeScript擴展了JavaScript的語法
TypeScript更像后端 Java c# 這樣的面向對象語言可以讓js開發大型企業項目
谷歌也在大力支持TypeScript的推廣,React ,VUE 都集成了TypeScript
TypeScript安裝
安裝
-- 安裝
npm install -g typescript
檢查是否安裝成功?
tsc -v?
1
2
3
4
5
編譯
-- 將.ts文件轉換成.js文件
tsc 文件名.ts
1
2
VsCode配置TypeScript
vscode配置TypeScript文件的自動編譯
在.ts文件夾下運行cmd 執行 tsc --init 命令 自動生成tsconfig.json配置文件
更改tsconfig.json配置文件 “outDir”: “./js”, 編譯后js輸出的目錄
任務 ——>運行任務 ——> 監視tsconfig.json 文件
vscode監視tsconfig報錯
1.管理員身份運行vs code
2.在終端執行:get-ExecutionPolicy,顯示Restricted
3.在終端執行:set-ExecutionPolicy RemoteSigned
4.在終端執行:get-ExecutionPolicy,顯示RemoteSigned
1
2
3
4
5
6
7
8
數據類型
TypeScript中為了使編寫的代碼更規范,更利于維護,增加了類型校驗,在聲明變量同時為它指定數據類型
格式 : 變量名: 數據類型 = 值
布爾類型(boolean)
// 布爾類型(boolean)?
let flag:boolean = false;
console.log(flag);
1
2
3
數值類型(number)
// 數值類型(number)
let num:number = 20;
console.log(num);
// 如果沒有值不是number類型那么ts編譯會報錯 但是瀏覽器可以正常輸出
// let num1:number = "20";
// console.log(num1);
1
2
3
4
5
6
7
字符串類型(string)
// 字符串類型(string)
let str:string = "Hello";
console.log(str);
1
2
3
數組類型(Array)
// 數組類型(Array) 直接為數組的每個元素指定同一類型
// 數組聲明方式一 ?數組聲明時指定 數組類型
let arr:number[] = [1,2,3,4];
console.log(arr);
// 數組聲明方式二 ?Array數組類型 給它指定泛型
let arr1:Array<string> = ["1","2","3"];
console.log(arr1);
// 數組聲明方式三 any類型
let arr2:any[] = ["this",0,"me"];
console.log(arr2);
1
2
3
4
5
6
7
8
9
10
11
12
13
元組類型(tuple)
// 元組類型(tuple) 屬于數組的一種 為數組的每一個元素指定一個類型
let arr3:[string,number,boolean] = ["this",1,true];
console.log(arr3);
1
2
3
枚舉類型(enum)
// 枚舉類型(enum)
/*?
? ? 聲明方式
? ? enum 枚舉名{
? ? ? ? 標識符=[值]
? ? }
*/
enum Color{
? ? red,
? ? blue,
? ? yellow="yellow"
}
// 如果枚舉沒有給枚舉元素賦值那么指向的是當前元素的下標
console.log(Color.blue);
// 給枚舉元素賦值 直接輸出當前元素的值
let y:Color = Color.yellow;
console.log(y);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
任意類型(any)
// 任意類型(any) 可以隨意指定類型
let sum:any = 123;
sum = "456";
console.log(sum);
1
2
3
4
5
null和undefined
// null和undefined 其他類型(never類型)數據類型的子類型
// 聲明未賦值 undefined
let str1:string;
console.log(str1); // 輸出 undefined 但是 ts編譯會報錯
// 指定string 或 undefined 如果不賦值 輸出undefined編譯不會出錯
let str2: string | undefined = "Hello";
console.log(str2);
// null 類型 只能為null
let str3:null = null;
console.log(str3);
// 為一個元素指定多種類型
let str4:string | undefined | null;
str4 = "Hello";
console.log(str4);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void類型
// void類型 :typescript中的void表示沒有任何類型,一般用于定義函數的時候函數沒有返回值
// 指定foo函數沒有返回值
function foo():void{
? ? console.log("void");
}
foo();
// 指定函數返回值類型
function get():number{
? ? return 100;
}
console.log(get());
1
2
3
4
5
6
7
8
9
10
11
12
13
never類型
// never類型:是其他類型(包括null,undefined)的子類型,代表從來不會出現的值,
// 這意味著never聲明的變量只能被never類型所賦值
var a:undefined;
a = undefined;
console.log(a);
var b:null;
b = null;
console.log(b);
// 從未出現的值 ?一般never類型不常用
var err:never;
err = (()=>{throw new Error("Error")})();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
函數
函數定義
// 函數定義
// 定義無返回值
function fun():void{
? ? console.log("void")
}
fun();
const fun1 = function():void{
? ? console.log("字面量函數void")
}
fun1();
// 定義帶返回值的函數
function fun2():string{
? ? return "返回值類型是string";
}
console.log(fun2());
const fun3 = function():string{
? ? return "字面量函數帶返回值";
}
console.log(fun3());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
函數參數
// 函數參數 在參數后面指定參數的類型
function fun4(name:string){
? ? return name;
}
console.log(fun4("小牛"));
1
2
3
4
5
6
可選參數
// 可選參數 ?
// 有時候需要age這個參數 有時候不需要 我們可以給age設置可選
function fun5(name:string,age?:number):any{
? ? // 如果有age這個參數 我們返回 name 和 age
? ? if(age){
? ? ? ? return `${name} --- ${age}`;
? ? }
? ? // 如果沒有我們只返回name
? ? return `${name}`;
}
console.log(fun5("牛小牛",22));
// 注意:可選參數盡量寫在形參列表最后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
默認參數
// 默認參數 ?
// 在參數定義時給它賦上默認值?
function fun6(name:string,age:number=20):any{
? ? return `${name}---${age}`;
}
console.log(fun6("小牛",21));
1
2
3
4
5
6
7
剩余參數
// 剩余參數 ... 用于參數列表不確定參數個數使用
// 注意:剩余參數寫在形參列表最后
function fun7(a:number,...result:number[]){
? ? let num:number = a;
? ? for(let v of result){
? ? ? ? num += v;
? ? }
? ? return num;
}
console.log(fun7(1,2,3,4,5));
1
2
3
4
5
6
7
8
9
10
11
函數重載
// 函數重載 ts支持函數重載
// 函數重載 : 函數名相同參數列表不同(參數的個數,順序,類型)有一個不同就都不相同
function getInfo(name:string):string;
function getInfo(age:number):number;
function getInfo(str:any):any{
? ? if(typeof str === "string"){
? ? ? ? return str;
? ? }else{
? ? ? ? return str;
? ? }
}
console.log(getInfo("hello"))
// 多個參數重載
function getData(name:string):string;
function getData(name:string,age:number):any;
function getData(name:string,age?:number):any{
? ? if(age){
? ? ? ? return `${name} --- ${age}`;
? ? }
? ? return `${name}`
}
console.log(getData("小牛",22));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
箭頭函數
// 箭頭函數 es6箭頭函數一樣
setTimeout(()=>console.log("箭頭函數的this依然指向上下文"));
1
2
3
類
ES5類
?// es5類
? ? // 最簡單的類
? ? function Student(){
? ? ? ? this.name = "小牛";
? ? ? ? this.age = 20;
? ? }
? ? const s = new Student();
? ? console.log(s.name);
? ? console.log("-----------------------")
? ? // 構造函數和原型鏈上增加方法
? ? function Person(){
? ? ? ? this.name = "小牛";
? ? ? ? this.age = 21;
? ? ? ? this.run = function(){
? ? ? ? ? ? console.log(this.name + "在運動");
? ? ? ? }
? ? }
? ? // 原型鏈上的屬性會被多個實例共享 構造方法不會
? ? Person.prototype.sex = "man";
? ? Person.prototype.work = function(){
? ? ? ? console.log(this.name + "在工作");
? ? }
? ? var p = new Person();
? ? console.log(p.name);
? ? p.run();
? ? p.work();
? ? console.log("-----------------------")
? ? // 類里面的靜態方法
? ? function Stu(){
? ? ? ? this.name = "小牛"; // 屬性
? ? ? ? this.age = 21;
? ? ? ? this.run = function(){ // 實例方法
? ? ? ? ? ? console.log(this.name + "在運動");
? ? ? ? }
? ? }
? ? // 靜態方法只能被類調用 不能被實例調用
? ? Stu.getInfo = function(){
? ? ? ? console.log("我是靜態方法")
? ? }
? ? // var stu = new Stu();
? ? // stu.getInfo();
? ? // 類 調用靜態方法
? ? Stu.getInfo();
? ? console.log("-----------------------")
? ? // 冒充繼承
? ? function Girl(){
? ? ? ? this.name = "MM";
? ? ? ? this.age = 20;
? ? ? ? this.run = function(){
? ? ? ? ? ? console.log(this.name + "運動")
? ? ? ? }
? ? }
? ? // 原型鏈
? ? Girl.prototype.color = "pink";
? ? Girl.prototype.work = function(){
? ? ? ? console.log(this.name + "工作")
? ? }
? ? // Web類 繼承Girl類 原型鏈 + 冒充繼承
? ? function Web(){
? ? ? ? // 對象冒充繼承 call apply bind
? ? ? ? Girl.call(this);
? ? }
? ? var w = new Web();
? ? // 冒充繼承可以繼承構造函數的屬性和方法
? ? w.run();
? ? // 冒充繼承可以繼承構造函數中的屬性和方法 但是不能繼承原型鏈的屬性和方法
? ? // w.work();?
? ? console.log("-----------------------")
? ? // ?原型鏈實現繼承 繼承Girl類
? ? function Father(){
? ? ? ? this.name = "牛小牛";
? ? ? ? this.age = 22;
? ? ? ? this.run = function(){
? ? ? ? ? ? console.log(this.name + "運動");
? ? ? ? }
? ? }
? ? Father.prototype.work = function(){
? ? ? ? console.log(this.name + "工作")
? ? }
? ? function Man(){
? ? }
? ? // 原型鏈繼承 可以繼承構造函數的屬性和方法,也可以繼承原型鏈上的屬性方法
? ? Man.prototype = new Father();
? ? var m = new Man();
? ? console.log(m.age);
? ? m.run();
? ? m.work();
? ? console.log("-----------------------")
? ? // 原型鏈繼承的問題?
? ? function F(name,age){
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? ? ? this.run = function(){
? ? ? ? ? ? console.log(this.name + "運動")
? ? ? ? }
? ? }
? ? F.prototype.sex = "man";
? ? F.prototype.work = function(){
? ? ? ? console.log(this.name + "工作")
? ? }
? ? var f = new F("花花牛",21);
? ? f.work();
? ? function FF(name,age){
? ? }
? ? FF.prototype = new F();
? ? var ff = new FF("雨花雨",21);
? ? // 原型鏈繼承傳參的問題
? ? ff.run();
? ? console.log("-----------------------")
? ? // 原型鏈 + 冒充繼承組合繼承模式
? ? function P(name,age){
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? ? ? this.run = function(){
? ? ? ? ? ? console.log(this.name + "運動")
? ? ? ? }
? ? }
? ? P.prototype.sex = "man";
? ? P.prototype.work = function(){
? ? ? ? console.log(this.name + "工作")
? ? }
? ? function PP(name,age){
? ? ? ? P.call(this,name,age);
? ? }
? ? PP.prototype = new P();
? ? var pp = new PP("雨花雨",22);
? ? pp.run();
? ? pp.work();
? ? console.log("-------------------------")
? ? // 原型鏈 + 冒充繼承的另一種方式
? ? function Man(name,age){
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? ? ? this.run = function(){
? ? ? ? ? ? console.log(this.name + "運動")
? ? ? ? }
? ? }
? ? Man.prototype.sex = "man";
? ? Man.prototype.work = function(){
? ? ? ? console.log(this.name + "工作")
? ? }
? ? function M(name,age){
? ? ? ? Man.call(this,name,age);
? ? }
? ? M.prototype = Man.prototype;
? ? var m = new M("奶牛",21);
? ? m.run();
? ? m.work();
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
ES6類
? // 類的聲明
? ? class Person{
? ? ? ? // 構造函數
? ? ? ? constructor(name,age) {?
? ? ? ? ? ? this.name = name;
? ? ? ? ? ? this.age = age;
? ? ? ? }
? ? ? ? // 定義方法
? ? ? ? show(name){
? ? ? ? ? ? console.log(this.name + "顯示")
? ? ? ? }
? ? }
? ? let p = new Person("小牛",21);
? ? console.log(p.name);
? ? console.log(p.age);
? ? p.show();
? ? console.log("------------------------------")
? ? // 靜態成員
? ? class Phone{
? ? ? ? // static 修飾的屬性和方法都是靜態的只屬于類
? ? ? ? static name = "Phone";
? ? ? ? static show(){
? ? ? ? ? ? console.log("靜態方法")
? ? ? ? }
? ? }
? ? // 靜態成員不能被實例化
? ? console.log(Phone.name);
? ? Phone.show();
? ? console.log("------------------------------")
? ? // 繼承 extends super
? ? class A{
? ? ? ? constructor(name,age){
? ? ? ? ? ? this.name = name;
? ? ? ? ? ? this.age = age;
? ? ? ? }
? ? ? ? eat(){
? ? ? ? ? ? console.log("吃飯")
? ? ? ? }
? ? }
? ? class B extends A{
? ? ? ? constructor(name,age,color,size){
? ? ? ? ? ? super(name,age);
? ? ? ? ? ? this.color = color;
? ? ? ? ? ? this.size = size;
? ? ? ? }
? ? ? ? // 重寫父類的方法
? ? ? ? eat(){
? ? ? ? ? ? console.log("吃晚飯")
? ? ? ? }
? ? }
? ? const b = new B("小牛",20,"skyblue",180);
? ? console.log(b.name);
? ? b.eat();
? ? console.log("------------------------------")
? ? // get set 方法?
? ? class Smart{
? ? ? ? // 用來獲取屬性的方法
? ? ? ? get price(){
? ? ? ? ? ? return "get方法獲取屬性"
? ? ? ? }
? ? ? ? // set 的時候 需要傳入一個參數
? ? ? ? set price(newValue){
? ? ? ? ? ? console.log("set方法設置了屬性")
? ? ? ? }
? ? }
? ? const smart = new Smart();
? ? smart.price = "set方法設置";
? ? console.log(smart.price)
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
TS類的聲明
// ts 類的聲明
class Person{
? ? name:string; ?// 屬性 默認public修飾?
? ? age:number;
? ? constructor(name:string,age:number){ // 構造函數 實例化的時候觸發
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? }
? ? show():void{
? ? ? ? console.log(this.name + "ts類中的方法")
? ? }
}
const person = new Person("小牛",21);
console.log(person.name);
console.log(person.age);
person.show();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
類的get set方法
get 和 set方法用于獲取和設置類的屬性
// 類的get set方法
class Student{
? ? name:string;
? ? constructor(name:string) {
? ? ? ? this.name = name;
? ? }
? ? // 用來設置屬性的值
? ? setName(name:string):void{
? ? ? ? this.name = name;
? ? }
? ? // 用來獲取屬性的值
? ? getName():string{
? ? ? ? return this.name;
? ? ?}
}
const student = new Student("大牛");
// 獲取沒有設置之前的值
console.log(student.getName());
// 設置值
student.setName("二牛")
// 獲取設置之后的值
console.log(student.getName());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
繼承
繼承使用關鍵字extends,調用父類使用super,子類繼承父類的屬性和方法,并且子類可以改寫父類的屬性和方法
// 類的繼承 extends super
class Phone{
? ? brand:string;
? ? price:number;
? ? constructor(brand:string,price:number){
? ? ? ? this.brand = brand;
? ? ? ? this.price = price;
? ? }
? ? show():void{
? ? ? ? console.log("Phone.show");
? ? }
}
class SmartPhone extends Phone{
? ? color:any;
? ? size:any;
? ? constructor(brand:string,price:number,color:any,size:any){
? ? ? ? super(brand,price);
? ? ? ? this.color = color;
? ? ? ? this.size = size;
? ? }
? ? // 重寫父類的方法
? ? show():any{
? ? ? ? console.log("SmartPhone.show")
? ? }
}
const smartPhone = new SmartPhone("iphoneX",7999,"black",5.5);
console.log(smartPhone.brand);
console.log(smartPhone.price);
console.log(smartPhone.color);
console.log(smartPhone.size);
smartPhone.show();
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
訪問修飾符
typescript為我們提供了三種訪問修飾符
public 公共的 作用范圍 本類 子類 類外部
protected*保護的 作用范圍 本類 子類
? private 私有的 作用范圍 本類
// 訪問修飾符
/*
? ? public 公共的 ?作用范圍 ?本類 子類 類外部
? ? protected 保護的 ?作用范圍 ?本類 子類?
? ? private 私有的 ?作用范圍 ?本類
*/?
class School{
? ? public name:string;
? ? protected age:number;
? ? private sex:string;
? ? constructor(name:string,age:number,sex:string){
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? ? ? this.sex = sex;
? ? }
? ? show():any{
? ? ? ? console.log("public---->" + this.name)
? ? ? ? console.log("protected---->" + this.age)
? ? ? ? console.log("private---->" + this.sex)
? ? }
}
const school = new School("xiaoniu",21,"man");
console.log(school.name);
school.show();
// age sex 分別是用 protected ?private 在類外部不能訪問所以編譯出錯
// console.log(school.age);
// console.log(school.sex);
class Teacher extends School{
? ? constructor(name:string,age:number,sex:string){
? ? ? ? super(name,age,sex);
? ? }
? ? show():any{?
? ? ? ? console.log("public---->" + this.name)
? ? ? ? console.log("protected---->" + this.age)
? ? ? ? // sex 是private修飾的 繼承過來的 sex是無法訪問的所以會報錯
? ? ? ? console.log("private---->" + this.sex)
? ? }
}
const teacher = new Teacher("daniu",22,"sex");
console.log(teacher.name);
teacher.show();
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
靜態成員
static修飾的靜態成員當類加載時就存在 只能被類調用 不能實例化
// 靜態成員
// 靜態成員當類加載時就存在 不能被實例化
class Per {
? ? public name:string;
? ? public age:number;
? ? // static聲明 靜態屬性
? ? static sex:any = "man";
? ? constructor(name:string,age:number) {
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? }
? ? static eat():void{
? ? ? ? console.log("靜態方法")
? ? }
}
const p = new Per("小牛",21);
console.log(p.name)
// 靜態成員只能被類調用
console.log(Per.sex)
Per.eat();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
多態
多態 :父類定義的方法不一定實現,讓繼承它的子類去實現,每個子類都有不同的表現形式
class Animal{
? ? public name:string;
? ? constructor(name:string){
? ? ? ? this.name = name;
? ? }
? ? eat(){
? ? ? ? console.log("吃的方法!")
? ? }
}
class Dog extends Animal{
? ? constructor(name:string){
? ? ? ? super(name);
? ? }
? ? eat(){
? ? ? ? console.log(this.name + "吃骨頭")
? ? }
}
const dog = new Dog("小狗狗");
dog.eat();
class Cat extends Animal{
? ? constructor(name:string){
? ? ? ? super(name);
? ? }
? ? eat(){
? ? ? ? console.log(this.name + "吃貓糧")
? ? }
}
const cat = new Dog("小花貓");
cat.eat();
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
抽象類
typescript中的抽象類:它是提供其他類繼承的基類,不能被直接實例化
abstract 關鍵字修飾的抽象類和抽象方法, 抽象類中的抽象方法不包含具體的實現并且必須在派生類中實現
abstract 修飾的方法只能在抽象類中
// 抽象類
abstract class Animal {
? ? public name:any;
? ? constructor(name:any){
? ? ? ? this.name = name;
? ? }
? ? abstract eat():any;
? ? // 非抽象方法 子類可以不實現它
? ? say(){
? ? ? ? console.log(this.name + "在說話")
? ? }
}
class Dog extends Animal{
? ? constructor(name:any){
? ? ? ? super(name);
? ? }
? ? // 抽象類的子類必須實現抽象類的抽象方法
? ? eat(){
? ? ? ? console.log(this.name + "吃骨頭")
? ? }
}
class Cat extends Animal{
? ? constructor(name:any){
? ? ? ? super(name);
? ? }
? ? eat(){
? ? ? ? console.log(this.name + "吃貓糧")
? ? }
}
const cat = new Cat("小花貓");
cat.eat();
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
接口
接口:是一種規范的定義,它定義了行為和動作的規范,接口起到了一種限制和規范的作用,接口定義了某一批類所需要的遵循的規范,接口不關心這些類的內部狀態數據,也不關心這些類里方法實現的細節,它只規定了這批類必須提供某些方法,提供了這些方法的類就可以滿足實際需要,typescript中的接口類似于java,同時還增加了更靈活的接口屬性,包括屬性,函數,可索引和類等。
json約束
約束了json的格式
// 接口 interface
interface Conn{
? ? host:string;
? ? port:number;
? ? username:string;
? ? password:string
}
// 約束了參數 及參數類型
function Connection(info:Conn):any{
? ? return `${info.host} --- ${info.port} --- ${info.username} --- ${info.password}`;
}
// 第一種傳參方式
?Connection({
? ? ?host:"localhost",
? ? ?port:3306,
? ? ?username:"root",
? ? ?password:"root"
?})
const conn = {
? ? host:"localhost",
? ? port:3306,
? ? username:"root",
? ? password:"root"
}
// 第二種傳參方式
console.log(Connection(conn))
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
可索引接口
可索引接口用來約束數組的格式
// 可索引接口 約束數組
interface Arr{
? ? // 約束數組 下標為number類型 的一個string類型數組
? ? [index:number]:string;
}
const ones:Arr = ["A","B","C"];
console.log(ones[0])
1
2
3
4
5
6
7
8
9
對象約束
// 對象的約束
interface Obj{
? ? [key:string]:any
}
const obj:Obj = {"name":"小牛"}
console.log(obj["name"])
1
2
3
4
5
6
7
可選操作符
屬性?:數據類型
表示可選 可以寫也可以不寫 可以通過編譯
interface IPerson{
? ? firstName:string,
? ? // ? 可選操作符?
? ? lastName?:string,
? ? sayHi:()=>string
}
// 接口約束對象
const customer:IPerson = {
? ? firstName:"Tom",
? ? lastName:"Tim",
? ? sayHi:():string=> "Hi Tom"
}
console.log(customer);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
類類型接口
// 類類型接口 ?約束類
interface Cla{
? ? name:string;
? ? eat():any;
}
// 類類型接口 ?類只能用 implements 實現
class Birage implements Cla{
? ? public name = "goods";
? ? eat(){
? ? ? ? console.log("吃東西")
? ? }
}
const br = new Birage();
console.log(br.name)
br.eat();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
聯合類型和接口
// 聯合類型和接口
interface RunOptions{
? ? program:string;
? ? commandline:string[] | string | (()=>string);
}
const options:RunOptions = {
? ? program:"tim",
? ??
? ? // 參數可以是字符串數組
? ? // commandline:[
? ? // ? ? "小牛",
? ? // ? ? "大牛"
? ? // ]
? ? // 參數可以使字符串
? ? // commandline:"Hi"
? ? // 參數可以是箭頭函數
? ? commandline:()=>"Hi Tim"
}
console.log(options.program)
console.log(options.commandline)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
接口封裝ajax
// 封裝ajax
interface Config{
? ? type:string;
? ? url:string;
? ? data?:string;
? ? dataType:string
}
function Ajax(config:Config):any{
? ? const xhr = new XMLHttpRequest();
? ? // 創建連接
? ? xhr.open(,config.type,config.url);
? ? // 發送請求
? ? xhr.send();
? ? xhr.onreadystatechange = function(){
? ? ? ? if(xhr.readyState == 4 && xhr.status == 200){
? ? ? ? ? ? console.log("成功")
? ? ? ? ? ? if(config.dataType == "json"){
? ? ? ? ? ? ? ? console.log(JSON.parse(xhr.responseText))
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? console.log(xhr.responseText)
? ? ? ? ? ? }
? ? ? ? }
? ? }?
}
Ajax({
? ? url:"http://localhost:8080/heroall",
? ? type:"get",
? ? dataType:"json"
})
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
函數類型接口
函數類型接口:對方法傳入的參數以及返回值進行約束
// 函數類型接口
interface encrypt{
? ? // 沒有函數體?
? ? (Key:string,value:string):string;
}
var md5 = function(Key:string,value:string):string{
? ? return Key + "<--->" + value;?
}
console.log(md5("root","root"))
1
2
3
4
5
6
7
8
9
10
11
12
接口繼承
接口可以繼承另一個接口來擴展自己
// 接口繼承 ?接口可以通過其他接口來擴展自己
interface Andy{
? ? eat():void;
}
interface anfn extends Andy{
? ? work():void;
}
class Program{
? ? age:number;
? ? constructor(age:number){
? ? ? ? this.age = age;
? ? }
? ? coding():void{
? ? ? ? console.log(this.age + "年齡加載")
? ? }
}
class Aniy extends Program implements anfn{
? ? name:string;
? ? constructor(age:number,name:string){
? ? ? ? super(age);
? ? ? ? this.name = name;
? ? }
? ? eat():void{
? ? ? ? console.log(this.name + "吃東西")
? ? }
? ? work():void{
? ? ? ? console.log(this.name + "工作")
? ? }
}
const aniy = new Aniy(20,"小牛");
aniy.coding();
aniy.eat();
aniy.work();
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
泛型
泛型:軟件工程中,我們不僅要創建一致的定義良好的API,同時也要考慮可重用性。 組件不僅能夠支持當前的數據類型,同時也能支持未來的數據類型,這在創建大型系統時為你提供了十分靈活的功能。
在像C#和Java這樣的語言中,可以使用泛型來創建可重用的組件,一個組件可以支持多種類型的數據。 這樣用戶就可以以自己的數據類型來使用組件。
通俗理解:泛型就是解決 類 接口 方法的復用性、以及對不特定數據類型的支持(類型校驗)
泛型函數
// 泛型拯救了 any ?泛型可以支持不特定的數據類型
// T 代表泛型?
function getDatas<T>(value:T):T{
? ? return value;
}
console.log(getDatas<number>(123));
console.log(getDatas<string>("小牛"));
1
2
3
4
5
6
7
8
9
泛型類
// 泛型類
class MinClass<T>{
? ? public list:T[] = [];
? ? add(value:T){
? ? ? ? this.list.push(value);
? ? }
? ? min():T{
? ? ? ? var minNum = this.list[0];
? ? ? ? for(let i=0;i<this.list.length;i++){
? ? ? ? ? ? if(minNum>this.list[i]){
? ? ? ? ? ? ? ? minNum = this.list[i];
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return minNum;
? ? }
}
// 實例化傳入的 number類型決定了 他真正的類型
var m1 = new MinClass<number>();
m1.add(1);
m1.add(2);
m1.add(3);
m1.add(4);
console.log(m1.min())
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
泛型接口
// 泛型接口
// 函數型接口泛型
interface ConfigFn{
? ? <T>(value:T):T;
}
var getFn:ConfigFn = function<T>(value:T):T{
? ? return value;
}
getFn<number>(1);
// 泛型接口
interface getData2<T>{
? ? (value:T):T;
}
var getData2 = function<T>(value:T):T{
? ? return value;
}
getData2<string>("小牛");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
裝飾器
裝飾器是一種特殊類型的聲明,它能夠被附加到類,方法,屬性或參數上,可以修改類的行為,通俗的講裝飾器就是一個方法,可以注入到類,方法,性或參數上來擴展類、方法,屬性或參數的功能。常見的裝飾器有:類裝飾器,方法裝飾器,屬性裝飾器,參數裝飾器。
裝飾器的寫法:普通裝飾器(無法傳參),裝飾器工廠(可傳參),裝飾器是過去幾年中JS最大的成就之一,已是ES7的標準特性之一
類裝飾器
類裝飾器:普通裝飾器(無法傳參)
// 類裝飾器 : 普通裝飾器 (不能傳參)
function logClass(params:any){?
? ? console.log(params); // params 代表當前類
? ? params.prototype.name = "普通裝飾器的屬性";
? ? params.prototype.run = function(){
? ? ? ? console.log("普通裝飾器原型動態添加方法")
? ? }
}
@logClass
class HttpClient{
}
const http:any = new HttpClient();
console.log(http.name);
http.run();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
裝飾器:工廠裝飾器(可傳參)
// 類裝飾器:工廠裝飾器(可以傳參)
function logClass(param:string){
? ? return function(target:any){
? ? ? ? console.log(target) // target 當前類
? ? ? ? console.log(param) // param 當前類傳進來的參數
? ? ? ? target.prototype.url = param;
? ? }
}
@logClass("http:www.xiaoniuniu.com")
class HttpClient{
}
var httpClient:any = new HttpClient();
console.log(httpClient.url);?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
屬性裝飾器
屬性裝飾器會被應用到屬性描述上,可以用來監視,修改或替換屬性的內容
屬性裝飾器會在運行時傳入兩個參數
? 1.對于靜態成員來說是類的構造函數,對于實例來說是類的原型對象
? 2.成員的名字
// 屬性裝飾器
function logProperty(params:any){ // params就是當前類傳遞進來的參數
? ? return function(target:any,attr:any){
? ? ? ? console.log(target)
? ? ? ? console.log(params)
? ? ? ? target[attr] = params;
? ? }
}
class HttpClient{
? ? @logProperty("http:www.niuxiaoniu.com")
? ? public url :any | undefined;
? ? getData(){
? ? ? ? console.log(this.url);
? ? }
}
var http = new HttpClient()
console.log(http.url)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
方法裝飾器
方法裝飾器會被應用到方法描述上,可以用來監視、修改或者替換方法定義
方法裝飾器會在運行時傳入下列3個參數
1.對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象
2.成員的名字
3.成員的屬性描述符
function get(param:any){
? ? return function(target:any,methodName:any,desc:any){
? ? ? ? console.log(target)
? ? ? ? console.log(methodName)
? ? ? ? console.log(desc)
? ? ? ? target.urlAPI = param;
? ? ? ? target.run = function(){
? ? ? ? ? ? console.log("方法裝飾器")
? ? ? ? }
? ? }
}
class HttpClient{
? ? url : any | undefined;
? ? constructor(){
? ? }
? ? @get("http://www.niuxiaoniu.com")
? ? getData(){
? ? ? ? console.log(this.url)
? ? }
}
const http:any = new HttpClient();
console.log(http.urlAPI)
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
方法參數裝飾器
參數裝飾器表達式會在運行時當作函數被調用,可以使用參數裝飾器為類的原型增加一些元素數據 ,傳入下列3個參數:
1.對于靜態成員來說是類的構造函數,對于實例成員是類的原型對象。
2.方法的名字。
3.參數在函數參數列表中的索引。
function logParam(param:any){
? ? return function(target:any,methodName:any,paramIndex:any){
? ? ? ? console.log(target)
? ? ? ? console.log(methodName)
? ? ? ? console.log(paramIndex)
? ? ? ? target.urlAPI = param;
? ? }
}
class HttpClient{
? ? getData(@logParam("123456") uuid:any){
? ? ? ? console.log(uuid);
? ? }
}
const http:any = new HttpClient();
http.getData(123456);
console.log(http.urlAPI)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
裝飾器執行順序
裝飾器執行順序 : 屬性裝飾器 ————> 方法裝飾器 ————> 方法參數裝飾器 ————> 類裝飾器
模塊化
模塊化是將一個大的程序,拆分成多個小文件,然后將小文件組合起來
模塊化優點:
防止命名沖突
代碼復用性
高維護性
模塊化主要由 import 和 export 構成
export 模塊對外暴露
import 引入暴露的模塊
export
單個暴露
// 單獨暴露 在需要暴露的內容前面加入 export關鍵字
export let school = "我愛學習";
export function getData(){
? ? console.log("我可以改變你")
}
1
2
3
4
5
6
7
統一暴露
let msg = "嘿嘿";
function getMsg(){
? ? console.log("哈哈")
}
export {msg , getMsg};
1
2
3
4
5
6
默認暴露
// 默認暴露 以對象形式暴露
export default{
? ? name:"Hello",
? ? show(){
? ? ? ? console.log("Hello Show");
? ? }
}
1
2
3
4
5
6
7
8
Import
默認引入
// 引入 將暴露的內容全部引入 并賦值給m1
import * as m1 from "./export";
1
2
3
解構賦值引入
// 解構賦值形式引入
import {msg,getMsg} from "./export2";
1
2
3
針對于默認暴露引入
import m2 from "./export3";
1
2
命名空間
命名空間:在代碼量較大的情況下,為了避免各種變量命名相沖突,可將相似功能的函數、類、接口等放置到命名空間內,同Java的包,TypeScript的命名空間可以將代碼包裹起來,只對外暴露需要在外部訪問的對象,命名空間內的對象通過export關鍵字對外暴露
命名空間和模塊的區別:
命名空間:內部模塊,主要用于組織代碼,避免命名沖突。
模塊:ts的外部模塊的簡稱,側重代碼的復用,一個模塊里可能會有多個命名空間
namespace A{
? ? interface Animal {
? ? ? ? name: string;
? ? ? ? eat(): void;
? ? }
? ? export class Dog implements Animal {
? ? ? ? name: string;
? ? ? ? constructor(name: string) {
? ? ? ? ? ? this.name = name;
? ? ? ? }
? ? ? ? eat(): void {
? ? ? ? ? ? console.log(`${this.name} ---- 吃骨頭!!!`);
? ? ? ? }
? ? }
? ? export class Cat implements Animal {
? ? ? ? name: string;
? ? ? ? constructor(name: string) {
? ? ? ? ? ? this.name = name;
? ? ? ? }
? ? ? ? eat(): void {
? ? ? ? ? ? console.log(`${this.name} ----吃貓糧!!!`);
? ? ? ? }
? ? }
}
const aDog = new A.Dog("小狗狗");
aDog.eat();
const aCat = new A.Cat("小喵喵");
aCat.eat();
————————————————
原文鏈接:https://blog.csdn.net/weixin_45764643/article/details/116465126
裝飾器:https://ninghao.net/blog/7384
總結
以上是生活随笔為你收集整理的TypeScript看完就会了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黄武林老师
- 下一篇: Mybatis缓存探索,查询集合后修改内