TypeScript學習
TypeScript
1.微軟開發的開源的組合語言
示列
function greeter(ts :string) {
return "hellow"+ts;
}
var test = "a";
let user = "Jane User";
document.body.innerHTML = greeter(user);
:string 表示的是型別註解
介面
interface person{ lastName:String; firstName:String; } function greeter(person:person) { return "hello"+person.firstName+" "+person.lastName; } let user = { firstName:"Jane",lastName:"User"} document.body.innerHTML = greeter(user);
類
class Student { fullName: string; constructor(public firstName: string, public middleInitial: string, public lastName: string) { this.fullName = firstName + " " + middleInitial + " " + lastName; } } interface Person { firstName: string; lastName: string; } function greeter(person: Person) { return "Hello, " + person.firstName + " " + person.lastName; } let user = new Student("Jane", "M.", "User"); document.body.innerHTML = greeter(user);
TypeScript基本資料型別
-
布林值
let isDone: boolean = false;
-
數字
let decLiteral: number = 6; let hexLiteral: number = 0xf00d; let binaryLiteral: number = 0b1010; let octalLiteral: number = 0o744;
-
字串 模板字串 ${}
let name: string = "bob"; name = "smith";
-
陣列
let list: number[] = [1, 2, 3];
-
元祖 Tuple
元祖相當於混個多種型別
// Declare a tuple type let x: [string, number]; // Initialize it x = ['hello', 10]; // OK // Initialize it incorrectly x = [10, 'hello']; // Error
-
列舉
-
任意值
對於一些現在還不算清楚的變數指定一個型別我們會採取任意型別
let notSure: any = 4; notSure = "maybe a string instead"; notSure = false; // okay, definitely a boolean
-
空值
-
Null和Undefined
是所有型別的子型別
-
Never
表示那些永不存在的值的型別
-
Object
代表的是非原始型別,也就是除了
number
,string
,boolean
,symbol
,null
或undefined
之外的型別。
使用方法
- tsc --init
ES5定義函式的方法
//普通函式的申明
function run() {
return "run"
}
//匿名函式宣告
var run2 = function() {
return "run"
}
ts中定義函式的方法
如果有返回值
//函式宣告需要返回宣告
function run():string{
return "run";
}
//匿名函式法
var fun2 = function():number{
return 123;
}
//ts中定義方法傳參
函式宣告
function getInfo(name:string.age:number):string{
return `${name} ----- ${age}`;
}
匿名函式
var getInfo = function(name:string.age:number):string{
return `${name} ----- ${age}`;
}
//沒有返回值的方法
function run():void{
return "age";
}
方法可選引數
function run(name:string,age?:number){
if(age){
return `${age}`;
}else{
return `${name}`;
}
}
?的意思是可選引數相當於可以傳入引數也可以不傳入引數
//可選引數必須到引數的最後面
預設引數
es5裡面沒法設定預設引數。es6和ts可以設定
function run(name:string,age:number =20){
if(age){
return `${age}`;
}else{
return `${name}`;
}
}
剩餘引數
function sum(a:number,b:number,c:number,d:number):number{
return a+b+c+d;
}
sum(1,2,3,4);
//三點運算子接受形參
function sum(...result:number[]):number{
var sum = 0;
for(var i = 0;i<result.length;i++){
sum+=result[i];
}
return sum;
}
sum(1,2,3,4);
函式過載
首先如果是es5出現同名的方法,下面的會替代上面的方法
function css (config){
}
function css (config,value){
}
//ts中的過載
function getInfo(name:string):string;
function getInfo(age:string):number;
function getInfo(str:any):any{
if(typeof str ==='string'){
return '我叫'+str
}else {
return '我的年齡'+str;
}
}
箭頭函式
setTimeout(()=>{
console.log("我要做一些事情了")
},1000)
//箭頭函式this指向上下文
es5建立物件和繼承
1.es5裡面的類
最簡單的類
function Person(){
this.name="1";
this.age=1;
}
var p = new Person();
alert(p.name);
2.建構函式和原型鏈裡面增加的方法
function Person(){
this.name="1";
this.age=1;
this.run = function(){
console.log(this.name+"運動");
}
}
Person.prptotype.sex="男";
Person.prptotype.work=function(){
}
var p = new Person();
p.work();
原型鏈上面的屬性會被多個例項分享 建構函式並不會這樣
3類裡面的靜態方法
function Person(){
this.name="1";
this.age=1;
this.run = function(){
console.log(this.name+"運動");
}
}
Person.prototype.sex="男";
Person.prototype.work=function(){
}
var p = new Person();
p.work()
Person.run = function(){
console.log("你好啊");
}
Person.run();
原型鏈上面的屬性會被多個例項分享 建構函式並不會這樣
4.es5的繼承
原型鏈+物件冒充的組合繼承模式
物件冒充
function Person(){
this.name="1";
this.age=1;
this.run = function(){
console.log(this.name+"運動");
}
}
//物件冒充實現繼承
function Web(){
Person.call(this)
}
var w = new Web();
w.run();//物件冒充可以繼承建構函式的屬性和方法
//物件冒充沒有辦法進行原型鏈的方法
使用原型鏈實現繼承
function Person(){
this.name="1";
this.age=1;
this.run = function(){
console.log(this.name+"運動");
}
}
function web(){
}
web.prototype = new Person();
//使用原型鏈的方法實現繼承
var w = new web();
w.run();
缺點:例項化子類沒有辦法給父類進行傳參
原型鏈+建構函式的組合構造模式
function Person(name,age){
this.name=name;
this.age=age;
this.run = function(){
console.log(this.name+"運動");
}
}
function web(name,age){
Person.call(this.name,this.age)
}
物件冒充例項化子類可以給父類傳參
原型鏈+物件冒充的二種方法
web.prototype = person.prototype
ts中如何定義一個類
class Person{
name:string; //屬性 前面省去了public
constructor(n:string){
//建構函式 例項化的時候觸發的方法
this.name = n;
}
run():void{
alert(this.name);
}
}
var p = new Person('張三');
p.run();
ts中如何實現繼承
extends super
class Person {
name:string;
constructor(name:string){
this.name = name;
}
run():string{
return `${this.name}在運動`;
}
}
var p = new Person('王五');
p.run();
class Web extends Person{
constructor(name:string){
super(name);
}
}
var w =new Web("lisi");
類裡面有三種修飾符
public 表示公有 類 子類 類外部都是可以訪問 預設為public型別
protected 保護型別 在類裡面,子類裡面可以訪問,在類外部是不能訪問的
private 私有化 類裡面可以訪問,其他都不能夠訪問
靜態方法
function Person(){
this.run1 = function(){
}
}
Person.name="哈哈哈"
Person.run()=function(){
}
var p = new Person();
class Person{
private name:string;
constructor(name:string){
this.name=name;
}
run(){
alert(`${this.name}在運動`);
}
work(){
alert(`${this.name}在工作`)
}
//靜態方法
static print(){
alert('print')
}
}
Person.print();
靜態方法沒有辦法直接呼叫 屬性
抽象類
abstract class Animal{
// 抽象類
public name:string;
constructor(name:string){
this.name=name;
}
abstract eat():any;
}
class Dog extends Animal{
constructor(name:string){
super(name);
}
eat(){
console.log(this.name+"吃糧食");
}
}
var d = new Dog('asas');
d.eat();
多型
父類定義一個方法不去實現,讓繼承它的子類去實現,每個子類有不同的表現
多型屬於繼承
class Animal{
name:string;
constructor(name:string){
this.name=name;
}
eat(){
console.log("吃的方法")
}
}
class Dog extends Animal{
constructor(name:string){
super(name)
}
eat(){
return this.name+"吃肉"
}
}
class cat extends Animal{
constructor(name:string){
super(name)
}
eat(){
return this.name+"吃老鼠";
}
}
介面的概念以及屬性型別介面
介面的作用,在面向物件的程式設計中,介面是一種規範的定義,他定義了行為和動作的規範,在程式設計裡面,介面起限制個規範的作用。介面定義了某一批類所需要遵循的規範,介面沒有必要關係這些類的內部狀態和資料,也不關心類裡面方法實現的細節。他只是規定了這批類裡面需要提供某些方法,提供這些方法的類可以滿足實際需要。類似於java,但是也是在裡面增加了一些其他的東西屬性、函式、索引型別
// ts定義方法傳引數
// function printLabel(label:string):void{
// console.log("print");
// }
//ts自定義方法對json進行約束
function printLabel(labelInfo:{label:string}):void{
console.log("print");
}
printLabel({label:"張三"});
//對批量方法傳入引數進行約束
//介面:行為和動作規範:對批量方法進行約束
interface fullName{
firstName:string; //注意;結束
secondName:string;
}
function printName(name:fullName):void{
//必須傳入物件 firstName secondName
console.log(name.firstName);
}
var obj = {
firstName:'張三',
secondName:'sa',
}
printName(obj);
輸出結果:張三
interface fullName{
firstName:String;
secondName:string;
age:number;
}
function printInfo(name:fullName){
console.log(name.firstName+name.secondName)
}
function printAge(info:fullName){
console.log(info.age);
}
var obj ={
age:20,
firstName:"ma",
secondName:"haitao",
}
printAge(obj);
輸出結果:20
介面可選屬性
ajax封裝
interface Config{
type:string;
url:string;
data?:string;
dataType:string;
}
function ajax(config:Config){
var xhr =new XMLHttpRequest();
xhr.open(config.type,config.url,true);
xhr.send(config.data);
xhr.onreadystatechange = function(){
if(xhr.readyState==4 && xhr.status==200){
console.log("成功")
if(config.dataType=='json'){
JSON.parse(xhr.responseText);
}else{
console.log(xhr.responseText);
}
}
}
}
ajax({
type:'get',
data:"name:",
url:'www.baidu.com',
dataType:'json',
})
函式型別介面
對於方法傳入的引數 以及返回值進行約束
1.加密函式型別介面
//加密的函式型別介面
interface encrypt{
(key:string,value:string):string;
}
var md5:encrypt = function(key:string,value:string):string{
return key+value;
}
md5('name','zahngsan')
2.可索引介面:陣列約束
2.1陣列物件的約束
// ts定義陣列的方式
var arr:number[]=[12,12];
var arr1:Array<string>=['111','222'];
//ts中介面定義陣列的方式
interface UserArr{
[index:number]:string;
}
var arr2:UserArr = ['1212','1212121']
console.log(arr2[0]);
2.2可索引介面對於物件的約束
3.類型別介面 對於類的約束
interface Animal {
name:string;
eat(str:string):void;
}
class Dog implements Animal{
name:string;
constructor(name:string){
this.name=name;
}
eat(){
console.log(this.name+"後")
}
}
//介面擴充套件:介面可以繼承介面
interface Animal {
eat():void;
}
interface Person extends Animal {
work():void;
}
泛型概念
軟體工程中,我們不僅需要建立一致性良好的API同時也是需要考慮重用性。組建不僅能夠支援當前的資料型別,同時也是能夠支援未來的資料型別
泛型主要是用來解決 類 介面 方法的複用性,以及對不特定資料型別的支援
泛型函式
//只能返回string型別資料
function getData(value:string):string{
return value;
}
//同時返回string型別和number型別
function fetData1(value:any):any{
return value;
}
//放棄了型別檢查
// T表示泛型。具體什麼類是呼叫這個方法的時候決定的
function getData<T>(value:T):T{
return value;
}
getData<number>(123);
getData<String>('aa');
泛型類
//泛型類:比如有一個最小堆演算法,需要同時只是返回數字和字串兩種型別
//通過類的泛型來實現
class MinClass{
public list:number[]=[];
add(num:number){
this.list.push(num);
}
min(){
var minNum=this.list[0];
for(var i=0;i<this.list.length;i++){
if(minNum>this.list[i]){
minNum=this.list[i];
}
}
return minNum;
}
}
var m=new MinClass();
m.add(2);
m.add(333);
m.add(11111);
m.add(454545);
m.min();
//改進版
class MinClass<T>{
public list:T[]=[];
add(num:T):void{
this.list.push(num);
}
min():T{
var minNum=this.list[0];
for(var i=0;i<this.list.length;i++){
if(minNum>this.list[i]){
minNum=this.list[i];
}
}
return minNum;
}
}
var m=new MinClass<number>();
m.add(2);
m.add(333);
m.add(11111);
m.add(454545);
泛型介面
//函式型別介面
interface ConfigFn{
(value1:string,value2:string):string;
}
var setData:ConfigFn = function(value1:string,value2:string):string{
return value1+value2;
}
setData('name','張三');
// 泛型型別介面
interface ConfigFn{
<T>(value1:T):T;
}
var getData:ConfigFn = function<T>(value:T){
return value;
}
getData<string>('asa');
interface ConfigFn{
<T>(value1:T):T;
}
function getData<T>(value:T):T{
return value;
}
var myGetData:ConfigFn<string>=getData;
myGetData('23')
// 泛型類深入講解
// 1.定義一個類
// 2.把類作為引數約束資料傳入的型別
class User{
username:string | undefined;
password:string | undefined;
}
class MysqlDb{
add(user:User):boolean{
return true;
}
}
var u =new User();
u.username = '張三';
u.password = '123456';
var Db = new MysqlDb();
Db.add(u);
class ArtucleCate{
title:string |undefined;
desc:string |undefined
status:number |undefined;
}
class MysqlDb{
add(info:ArtucleCate):boolean{
console.log(info);
return true;
}
}
var a =new ArtucleCate();
a.title = "國內";
a.desc = "國內新聞";
a.status = 1;
var Db = new MysqlDb();
Db.add(a);
利用泛型進行實現
class MysqlDb<T>{
add(info:T):boolean{
console.log(info);
return true;
}
}
//想給user表增加資料
// 1、定義一個;User類和資料庫進行對映
class User{
username:string | undefined;
password:string | undefined;
}
var u = new User();
u.username = "張三";
u.password = "123456";
var Db =new MysqlDb();
//2定義一個ArticleCate 和資料庫進行對映
class ArticleCate {
title:string | undefined;
desc:string | undefined;
status:number | undefined;
constructor(params:{
title:string | undefined;
desc:string | undefined;
status?:number | undefined;
}){
this.title = params.title;
this.desc = params.desc;
this.status = params.status;
}
}
class MysqlDb<T>{
add(info:T):boolean{
console.log(info);
return true;
}
}
var a = new ArticleCate({
title:"分類",
desc:"1111"
});
var Db =new MysqlDb<ArticleCate>();
Db.add(a)
TypeScript 型別、介面、類 、泛型 綜合使用--TypeScript封裝統一操作Mysql Mongodb Mssql的底層類庫
/**
*
* 功能:定義一個操作資料庫的庫 支援 Mysql Mssql MongoDb
* 要求1: Mysql MsSql MOngoDb 功能一樣 都有add updata delete get方法
*
* 注意:約束統一的規範、以及程式碼的重用
*
* 解決方案:需要約束規範所以要定義介面,需要程式碼重用所以要用到泛型
* 1.介面:在面向物件的程式設計中,介面是一種定義規範,他定義了行為和動作規範
* 2.泛型:通俗來說就是解決 類、介面、方法的複用性
*
*/
interface DBI<T>{
add(info:T,id:number):boolean;
update(info:T,id:number):boolean;
delete(id:number):boolean;
get(id:number):any[];
}
//定義一個操作mysql資料庫的類
//注意實現泛型介面 這個類也是一個泛型類
class MysqlDb<T> implements DBI<T>{
add(info: T, id: number): boolean {
throw new Error("Method not implemented.");
}
update(info: T, id: number): boolean {
throw new Error("Method not implemented.");
}
delete(id: number): boolean {
throw new Error("Method not implemented.");
}
get(id: number): any[] {
throw new Error("Method not implemented.");
}
}
//定義一個操作mysql資料庫的類
class MySqlDb<T> implements DBI<T>{
add(info: T, id: number): boolean {
throw new Error("Method not implemented.");
}
update(info: T, id: number): boolean {
throw new Error("Method not implemented.");
}
delete(id: number): boolean {
throw new Error("Method not implemented.");
}
get(id: number): any[] {
throw new Error("Method not implemented.");
}
}
//操作使用者表 定義一個User類和資料表做對映
class User{
username:string |undefined;
password:string |undefined;
}
var u = new User();
u.username = "張三";
u.password = "1234";
var oMysql=new MySqlDb<User>();
oMysql.add(u);
模組以及模組化封裝
內部模組稱作是名稱空間
外部模組稱作是模組,在自身的作用域執行
引入
import {getData} from './xxx/asa'
名稱空間
避免命名衝突
namespac A{
}
如果需要直接export就行了
裝飾器
裝飾器:裝飾器是一種特殊的沈明,他能夠被加到類宣告,方法,屬性或者是引數上,可以修改類的行為
通俗的講裝飾器就是一個方法:可以注入到類、方法、屬性引數上擴充套件類、屬性、方法、引數的功能
常見的裝飾器:類裝飾器、屬性裝飾器、方法裝飾器、引數裝飾器
裝飾器的寫法:普通裝飾器(無法傳參)、裝飾器工廠(可以傳參)
裝飾器是js最大的成就之一,ES7標準特性之一
//類裝飾器:在類宣告之前就被宣告
//1.類裝飾器
//裝飾器
function LogClass(params:any){
console.log(params);
//params就是當前類
params.protitype.run = function(){
}
params.protitype.age = 22;
}
//呼叫裝飾器
@LogClass
class HttpClient {
constructor(){
}
getData(){
}
}
類裝飾器 裝飾器工廠
可以傳參
function LogClass(params:string){
return function(target:any){
console.log(target);
console.log(params);
target.prptotype.apiUrl = params;
}
}
@LogClass('hello')
class HttpClient{
constructor(){
}
getData(){
}
}
var http = new HttpClient();
1、類裝飾器
下面是一個過載建構函式的例子。
類裝飾器表示式會在執行時當作函式被呼叫,類的建構函式作為其唯一的引數。
如果類裝飾器返回一個值,它會使用提供的建構函式來替換類的宣告。
*/
/*
function logClass(target:any){
console.log(target);
return class extends target{
apiUrl:any='我是修改後的資料';
getData(){
this.apiUrl=this.apiUrl+'----';
console.log(this.apiUrl);
}
}
}
@logClass
class HttpClient{
public apiUrl:string | undefined;
constructor(){
this.apiUrl='我是建構函式裡面的apiUrl';
}
getData(){
console.log(this.apiUrl);
}
}
var http=new HttpClient();
http.getData();
*/
屬性裝飾器
/*
2、屬性裝飾器
屬性裝飾器表示式會在執行時當作函式被呼叫,傳入下列2個引數:
1、對於靜態成員來說是類的建構函式,對於例項成員是類的原型物件。
2、成員的名字。
*/
//類裝飾器
function logClass(params:string){
return function(target:any){
// console.log(target);
// console.log(params);
}
}
//屬性裝飾器
function logProperty(params:any){
return function(target:any,attr:any){
console.log(target);
console.log(attr);
target[attr]=params;
}
}
@logClass('xxxx')
class HttpClient{
@logProperty('http://itying.com')
public url:any |undefined;
constructor(){
}
getData(){
console.log(this.url);
}
}
var http=new HttpClient();
http.getData();
/*
3、方法裝飾器
它會被應用到方法的 屬性描述符上,可以用來監視,修改或者替換方法定義。
方法裝飾會在執行時傳入下列3個引數:
1、對於靜態成員來說是類的建構函式,對於例項成員是類的原型物件。
2、成員的名字。
3、成員的屬性描述符。
*/
/*
/*
//方法裝飾器一
function get(params:any){
return function(target:any,methodName:any,desc:any){
console.log(target);
console.log(methodName);
console.log(desc);
target.apiUrl='xxxx';
target.run=function(){
console.log('run');
}
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
@get('http://www.itying,com')
getData(){
console.log(this.url);
}
}
var http:any=new HttpClient();
console.log(http.apiUrl);
http.run();
*/
//方法裝飾器二
/*
function get(params:any){
return function(target:any,methodName:any,desc:any){
console.log(target);
console.log(methodName);
console.log(desc.value);
//修改裝飾器的方法 把裝飾器方法裡面傳入的所有引數改為string型別
//1、儲存當前的方法
var oMethod=desc.value;
desc.value=function(...args:any[]){
args=args.map((value)=>{
return String(value);
})
oMethod.apply(this,args);
}
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
@get('http://www.itying,com')
getData(...args:any[]){
console.log(args);
console.log('我是getData裡面的方法');
}
}
var http=new HttpClient();
http.getData(123,'xxx');
*/
/*
4、方法引數裝飾器
引數裝飾器表示式會在執行時當作函式被呼叫,傳入下列3個引數:
1、對於靜態成員來說是類的建構函式,對於例項成員是類的原型物件。
2、引數的名字。
3、引數在函式引數列表中的索引。
*/
// function logParams(params:any){
// return function(target:any,methodName:any,paramsIndex:any){
// console.log(params);
// console.log(target);
// console.log(methodName);
// console.log(paramsIndex);
// target.apiUrl=params;
// }
// }
// class HttpClient{
// public url:any |undefined;
// constructor(){
// }
// getData(@logParams('xxxxx') uuid:any){
// console.log(uuid);
// }
// }
// var http:any = new HttpClient();
// http.getData(123456);
// console.log( http.apiUrl);
//裝飾器執行順序
//屬性》方法》方法引數》類
// 如果有多個同樣的裝飾器,它會先執行後面的
function logClass1(params:string){
return function(target:any){
console.log('類裝飾器1')
}
}
function logClass2(params:string){
return function(target:any){
console.log('類裝飾器2')
}
}
function logAttribute1(params?:string){
return function(target:any,attrName:any){
console.log('屬性裝飾器1')
}
}
function logAttribute2(params?:string){
return function(target:any,attrName:any){
console.log('屬性裝飾器2')
}
}
function logMethod1(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法裝飾器1')
}
}
function logMethod2(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法裝飾器2')
}
}
function logParams1(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法引數裝飾器1')
}
}
function logParams2(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法引數裝飾器2')
}
}
@logClass1('http://www.itying.com/api')
@logClass2('xxxx')
class HttpClient{
@logAttribute1()
@logAttribute2()
public apiUrl:string | undefined;
constructor(){
}
@logMethod1()
@logMethod2()
getData(){
return true;
}
setData(@logParams1() attr1:any,@logParams2() attr2:any,){
}
}
var http:any=new HttpClient();