TypeScript入门基础

1.TypeScript安装

安装

npm install -g typescript

在这里插入图片描述
检测ts是否安装成功

tsc -v

在这里插入图片描述

第一个ts文件

新建一个文件夹用vscode打开并创建一个ts文件
在这里插入图片描述
因为浏览器不支持ts和es6语法,所以需要有一个编译的过程将ts转换成es5语法
在这里插入图片描述
在这里插入图片描述

设置自动编译

新建一个文件夹testinit并在cmd中进入这个目录并键入tsc --init命令
在这里插入图片描述
在该目录就生成了一个tsconfig.json的文件
在这里插入图片描述
修改该配置文件的outDir部分
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我这里报了错
在这里插入图片描述
解决办法一:
具体操作为:
右击VSCode快捷键,选择属性,在兼容性模块中选择以管理员身份运行,结束之后重启VSCode,如果不行的话重启一下电脑
然后在终端分别执行如下命令

在终端执行:get-ExecutionPolicy,显示Restricted
 
在终端执行:set-ExecutionPolicy  RemoteSigned
 
在终端执行:get-ExecutionPolicy,显示RemoteSigned

在这里插入图片描述
重新执行之后,js目录自动生成了,每次保存操作都会自动编译代码了。
在这里插入图片描述
解决办法二:
直接在cmd控制台执行tsc --watch index.ts

2.数据类型

ts中的数据类型有:

布尔类型(boolean)
数字类型(number)
字符串类型(string)
数组类型(array)
元组类型(tuple)
枚举类型(enum)
任意类型(any)
nullundefined
void类型
never类型

布尔类型

// 布尔类型(boolean) true false
var flag:boolean=true

// flag='str'  
//- error TS2322: Type 'string' is not assignable to type 'boolean'.
//定义flag的类型之后就不能随意更改类型了,flag只能为true或false

flag=false

es5

var flag = true;

flag = false;

数字类型

// 数字类型(number)
var  a:number=123
console.log(a)

es5

var a = 123;
console.log(a);

字符串类型

// 字符串类型(string)
var  str:string ='this is ts'
console.log(str)

es5

var str = 'this is ts';
console.log(str);

数组类型

// 数组类型(array)
  //es5 
  var arr=[1,2,'3',4]

  //第一种定义方式

  let arr:number[]=[1,2,2,3,45]//数组里面只能写数字

  let arr2:string[]=['js','ts','node']//数组里面只能是字符串


  //第二种定义方式

  let arr3:Array<number>=[12,35,64,11]//泛型方式
  
  let arr4:Array<string>=['java','node','js']//泛型方式

es5

//第一种定义方式
let arr = [1, 2, 2, 3, 45]; //数组里面只能写数字
let arr2 = ['js', 'ts', 'node']; //数组里面只能是字符串
//第二种定义方式
let arr3 = [12, 35, 64, 11]; //泛型方式
let arr4 = ['java', 'node', 'js']; //泛型方式

元组类型

// 元组类型(tuple)
let tuplearr:[string,number,boolean]=['js',12,true]//可以指定数组中的元素类型

es5

let tuplearr = ['js', 12, true]; 

枚举类型

// 枚举类型(enum)
enum Flag{success=1,error=-1}
 
 var f:Flag=Flag.success

 console.log(f)

 //如果定义枚举时没有赋值那么默认输出枚举值的下标

 enum Color{green,blue,red}

 var c:Color=Color.red

 console.log(c) //2

 //如果有如下情况
 enum Color2{green,blue=6,red}

 var c2:Color2=Color2.green
 var c3:Color2=Color2.blue
 var c4:Color2=Color2.red

 console.log(c2) //0
 console.log(c3) //6
 console.log(c4) //7

es5

// 枚举类型(enum)
var Flag;
(function (Flag) {
    Flag[Flag["success"] = 1] = "success";
    Flag[Flag["error"] = -1] = "error";
})(Flag || (Flag = {}));
var f = Flag.success;
console.log(f);
//如果定义枚举时没有赋值那么默认输出枚举值的下标
var Color;
(function (Color) {
    Color[Color["green"] = 0] = "green";
    Color[Color["blue"] = 1] = "blue";
    Color[Color["red"] = 2] = "red";
})(Color || (Color = {}));
var c = Color.red;
console.log(c); //2
//如果有如下情况
var Color2;
(function (Color2) {
    Color2[Color2["green"] = 0] = "green";
    Color2[Color2["blue"] = 6] = "blue";
    Color2[Color2["red"] = 7] = "red";
})(Color2 || (Color2 = {}));
var c2 = Color2.green;
var c3 = Color2.blue;
var c4 = Color2.red;
console.log(c2); //0
console.log(c3); //6
console.log(c4); //7

任意类型

var numone:any=123

numone='str'
numone=true

console.log(numone)

用处

//任意类型的用处
var box=document.getElementById('#box')
box.style.color='red'

// 这里会报错 error TS2531: Object is possibly 'null'.

修改为

var box:any=document.getElementById('#box')
box.style.color='red'

es5

var numone = 123;
numone = 'str';
numone = true;
console.log(numone);
//任意类型的用处
var box = document.getElementById('#box');
box.style.color = 'red';
// error TS2531: Object is possibly 'null'.

null和undefined

// null 和 undefined  其他(never类型)数据类型的子类型

// var numtwo:number
// console.log(numtwo)//输出undefined

var numtwo:undefined
console.log(numtwo)//输出undefined

var numthree:number | null | undefined 
numthree=123
console.log(numtwo)//如果定以后没有赋值就输出undefined

// null类型与undefined类似

es5

// null 和 undefined  其他(never类型)数据类型的子类型
// var numtwo:number
// console.log(numtwo)//输出undefined
var numtwo;
console.log(numtwo); //输出undefined
var numthree;
numthree = 123;
console.log(numtwo); //如果定以后没有赋值就输出undefined
// null类型与undefined类似

void类型


// void类型 ts中的void表示没有任何类型,一般用于定义方法的时候方法没有返回值

function run(){
   console.log('run...')
}
run()

//表示方法没返回任何类型
function run2():void{
   console.log('running...')
}
run2()

// 错误写法
// function run2():undefined{
//     console.log('running...')
// }
// run2()

// 正确写法
function run3():number{
    return 123
}
run3()

es5

// void类型 ts中的void表示没有任何类型,一般用于定义方法的时候方法没有返回值
function run() {
    console.log('run...');
}
run();
//表示方法没返回任何类型
function run2() {
    console.log('running...');
}
run2();
// 错误写法
// function run2():undefined{
//     console.log('running...')
// }
// run2()
// 正确写法
function run3() {
    return 123;
}
run3();

never类型

// never类型 :是其他类型(包括null和undefined)的子类型,代表从不会出现的值

// 这意味着声明never的变量只能被never类型所赋值

var q:undefined
q=undefined

var w:null
w=null

var e:never

// e=123//错误写法

e=(()=>{
    throw new Error('异常')
})()

es5

// never类型 :是其他类型(包括null和undefined)的子类型,代表从不会出现的值
// 这意味着声明never的变量只能被never类型所赋值
var q;
q = undefined;
var w;
w = null;
var e;
// e=123//错误写法
e = (() => {
    throw new Error('异常');
})();

3.函数

es5中函数定义

// es5中声明函数
function run11(){
    return '123'
}
var run22=function(){
    return 'run2'
}

ts中函数定义

1.声明函数

// 1.函数声明法
function funrun():string{
    return 'funrun'
}
//错误写法
// function funrun2():string{
//     return 1233
// }
//2.匿名函数
var funrun3=function():number{
    return 123
}
funrun3()

2.ts中定义方法传参

function getInfo(name:string,age:number):string{
   return `${name}--${age}`
}

getInfo('胡桃',16)

//匿名函数
var getInfo2=function(name:string,age:number):string{
   return `${name}--${age}`
}
getInfo2('甘雨',16)

//没有返回值的函数

function run4():void{
   console.log('123456')
}
run4()

3.可选参数

//es5里面方法的实参和形参可以不一样,但ts中必须一样,如果不一样就需要配置可选参数
function getInfo3(name:string,age?:number):string{
    if(age){
        return `${name}--${age}`
    }else{
        return `${name}--年龄保密`
    }
}
getInfo3('胡桃')//必须在可选参数后面加一个?,不然会报错
//注意:建议将可选参数配置在参数的后面,而不是这样写getInfo3(name?:string,age:number)

4.默认参数

// es5中没法设置默认参数es6和ts中都可以设置默认参数
function getInfo4(name:string,age:number=30):string{
 if(age){
     return `${name}--${age}`
 }else{
     return `${name}--年龄保密`
 }
}

getInfo4('胡桃')//胡桃--30
getInfo4('胡桃',16)//胡桃--16

5.剩余参数

function sum(a:number,b:number,c:number,d:number):number{
  return a+b+c+d
}
sum(1,2,3,4)

// es6中使用扩展运算符...来接收参数

function sum2(...result:number[]):number{
  var sum=0;
  for(var i=0;i<result.length;i++){
      sum+=result[i];
  }
  return sum;
}
sum2(1,2,3,4)

函数重载

  • java中方法的重载:重载指的是两个或者两个以上同名函数,但它们的参数不一样,这时会出现函数重载的情况。
  • typescript中的重载:通过为同一个函数提供多个函数类型定义来试下多种功能的目的。
//ts为了兼容es5,es6重载的写法和java有区别

// es5中出现同名方法,下面的方法会覆盖上面的方法
function ajax(config){

}
function ajax(config,value){

}

ts中的重载

//ts中的重载
function getUserInfo(name:string):string;
function getUserInfo(age:number):number;
function getUserInfo(str:any):any{
   if(typeof str=='string'){
       return '我叫:'+str
   }else{
       return '我的年龄是'+str
   }
}

getUserInfo('行秋')//我叫行秋
getUserInfo(16)//我的年龄是16
// getUserInfo(true)//报错
function getUserInfo2(name:string):string;
function getUserInfo2(name:string,age:number):string;
function getUserInfo2(name:any,age?:any):any{
  if(age){
      return '我叫:'+name+'我的年龄为:'+age
  }else{
      return '我叫:'+name
  }
}

getUserInfo2('七七')//我叫:七七
// getUserInfo2(132)//报错
getUserInfo2('凝光',18)//我叫:凝光我的年龄为:18

箭头函数

// 箭头函数 this指向上下文
setTimeout(function(){
console.log(11)
},1000)

setTimeout(() => {
    console.log(11)
}, 1000);

4.类

es5中的类

1.简单的类

// 1.简单的类
function Person(){
  this.name='胡桃';
  this.age=10;

  this.run=function(){//实例方法
      console.log('this is class in es5!')
  }
}
var p=new Person();

  console.log(p.name)//胡桃

  p.run()

  //原型链增加属性或方法
  Person.prototype.sex="女"
  Person.prototype.work=function(){
      console.log(this.name+"是往生堂堂主!")
  }

2.静态方法

//2.类里面的静态方法
  Person.getInfo=function(){
      console.log('我是静态方法')
  }
  //调用
  Person.getInfo();

3.继承

继承模式:原型链+对象冒充的组合继承模式

//3.es5中的继承
function Son(){
    Person.call(this)//对象冒充实现继承
}
var son=new Son();
son.run()
son.work()//报错,无法继承原型链上的属性和方法

//原型链继承:可以继承构造函数里面的属性和方法,也可以继承原型链上的属性和方法
function Son2(){

}
Son2.prototype=new Person()
var s=new Son2();
s.run()
s.work()//两个方法都正常执行

以上继承出现的问题:

function Animal(name,sex){
    this.name=name;
    this.sex=sex;
    this.run=function(){
        console.log(this.name+'喜欢吃鱼!')
    }
}

function Cat(name,sex){

}
Cat.prototype=new Animal()
var c=new('小花猫','女') //实例化子类无法给父类传参
c.run()//undefined喜欢吃鱼!
//这里的name值拿不到

所以修改为 原型链+对象冒充的组合继承模式

function Animal(name,sex){
    this.name=name;
    this.sex=sex;
    this.run=function(){
        console.log(this.name+'喜欢吃鱼!')
    }
}
function Cat(name,sex){
    Animal.call(this,name,sex) //对象冒充继承 实例化子类可以给父类传参

}
Cat.prototype=new Animal()
var c=new('小花猫','女') //实例化子类无法给父类传参
c.run()//小花猫喜欢吃鱼!

另一种写法:

//另一种写法
function Animal(name,sex){
    this.name=name;
    this.sex=sex;
    this.run=function(){
        console.log(this.name+'喜欢吃鱼!')
    }
}

function Cat(name,sex){
    Animal.call(this,name,sex) //对象冒充继承 实例化子类可以给父类传参

}
Cat.prototype=Animal.prototype
var c=new('小花猫','女') //实例化子类无法给父类传参
c.run()//小花猫喜欢吃鱼!

ts中的类

1.ts中类的定义

//es5
function Person(name){
  this.name=name
  this.run=function(){
      console.log(this.name)
  }
}
var p=new Person('胡桃')
p.run();
//ts
class Person{
 name:string; //属性 前面省略了public 关键字
 constructor(name:string){//构造函数 实例化类的时候触发的方法
     this.name=name;
 }
 run():void{
     console.log(this.name)
 }
}

var p=new Person('胡桃')
p.run();
class Person{
  name:string; //属性 前面省略了public 关键字
  constructor(name:string){//构造函数 实例化类的时候触发的方法
      this.name=name;
  }
  run():void{
      console.log(this.name)
  }

  getName():string{
      return this.name
  }
  setName(name:string):void{
      this.name=name
  }
}

var p=new Person('胡桃')
p.run();
console.log(p.getName())//胡桃

p.setName('七七')
console.log(p.getName())//七七

2.ts中的继承

使用关键字extends super

class Person{
    name:string; 
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在跑步`
    }
}

var p=new Person('胡桃')
console.log(p.run())//胡桃在跑步

    // 继承
class Son extends Person{
    constructor(name:string){
        super(name)
    }
    work(){
        console.log(`${this.name}+在工作`)
    }
}
var s=new Son('七七')
console.log(s.run())//七七在跑步 
s.work()//七七在工作

3.类里面的修饰符

ts里面定义属性的时候给我们提供了三种修饰符

  • public 共有 在类里面、子类、类外面都可以访问
  • protected 保护类型 在类里面、子类里面可以访问,在类外部没法访问
  • private 私有 在类里面可以访问、子类、类外部都没法访问

注意:属性不加修饰符默认为public

//public
class Person{
    public name:string; 
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在跑步`
    }
}

var p=new Person('胡桃')
console.log(p.name)//胡桃
//protected
class Person{
    protected name:string; 
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在跑步`
    }
}

var p=new Person('胡桃')
console.log(p.name)//报错 
//Property 'name' is protected and only accessible within class 'Person' and its subclasses.
//private
class Person{
    private name:string; 
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在跑步`
    }
}

var p=new Person('胡桃')
console.log(p.name)//报错

4.静态属性 静态方法

//es5
function Person(){
    this.run1=function(){

    }
}
Person.name="胡桃"//静态属性
Person.run2=function(){//静态方法

}
var p=new Person()
console.log(Person.name)
Person.run2()//静态方法的调用
//ts
class Person{
 	public name:string;
    static sex='女';
    constructor(name:string){
        this.name=name;
    }
    run(){//实例方法
        console.log(this.name+'在跑步')
    }
    work(){
        console.log(this.name+'在工作')
    }

    static print(){//静态方法
        console.log('print静态方法!'+this.sex)
    }
}

var p =new Person('胡桃')
p.run()
Person.print()//静态方法调用
console.log(Person.sex)

总结:静态方法就是把一个方法当做属性来使用

5.多态

概念:父类定义一个方法不去实现,让继承它的子类去实现,每一个子类有不同的表现。多态是属于继承的

class Animal{
    name:string;
    constructor(name:string){
        this.name=name;
    }
    eat(){
        console.log('喜欢吃')
    }
}

class Cat extends Animal{
    constructor(name:string){
        super(name)
    }
    eat() {
        return this.name+'吃鱼'
    }
}
class Dog extends Animal{
    constructor(name:string){
        super(name)
    }
    eat() {
        return this.name+'吃骨头'
    }
}

6.抽象类

概念:它是提供其他类继承的基类,不能直接被实例化

用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现

abstract抽象方法只能放在抽象类里面

抽象类和抽象方法用来定义标准:Animal这个类要求它的子类必须包含eat方法

//标准:
abstract class Animal {
    public name:string;
    constructor(name:string){
        this.name=name;
    }
    abstract eat():any;
}


class Dog extends Animal{
    
    constructor(name:any){
        super(name)
    }
    //抽象类的子类必须实现抽象类里面的抽象方法,不然会出现报错
    eat() {
        console.log(this.name+'吃粮食')
    }
}
var d=new Dog('小狗狗');
d.eat()

5.接口

接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用。
接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。
typescrip中的接口类似于java,同时还增加了更灵活的接口类型,包括属性、函数、可索引和类等。

属性接口

属性接口:对json的约束

//ts中定义方法
function printLabel():void{
    console.log('printLabel')
}
printLabel()

//ts中传入参数
function printLabel(label:string):void{
    console.log('printLabel')
}
printLabel('1234')
//传入json
function printLabel(labelInfo:{name:string}):void{
    console.log('printLabel')
}
printLabel('1234')//错误写法

printLabel({label:'胡桃'})//错误写法

printLabel({name:'胡桃'})//正确写法

对批量方法传入参数进行约束
接口:行为和动作的规范,对批量方法进行约束

interface FullName{
    firstName:string;
    secondName:string;
}

function printName(name:FullName){
    //传入对象 firstName secondName
    console.log(name.firstName+'--'+name.secondName)
}

printName('1354')//错误写法

var obj={
    age:18,
    firstName:'胡桃',
    secondName:'七七'
}
printName(obj) //正确写法

可选属性接口

interface FullName{
    firstName:string;
    secondName?:string
}

function getName(name:FullName){
    console.log(name)
}
getName({
    secondName:'qiqi',
    firstName:'hutao'
})

getName({
    firstName:'hutao'
})//给接口中的属性加一个?就表示该属性可选

函数类接口

函数类型接口:对方法传入的参数 以及返回值进行约束

//加密的函数类型接口
interface encrypt{
    (key:string,value:string):string;
}

var md5:encrypt=function(key:string,value:string):string{
    //模拟操作
    return key+value;
}
console.log(md5('name','qiqi'))//nameqiqi

可索引接口

可索引接口:数组、对象的约束

//ts定义数组
var array1:number[]=[132,45,1235]

var array2:Array<string>=['123','321']
//对数组的约束
interface UserArr{
    [index:number]:string
}

var array:UserArr=['123','321'];
console.log(array[0])//123

// 对对象的约束
interface UserObj{
    [index:string]:string
}
var array:UserObj={name:'七七'}

类类型接口

类类型接口:对类的约束 和抽象类有点类似

interface AnimalDog{
    name:string;
    eatFood(str:string):void;
}
class Doggy implements AnimalDog{
    name:string;
    constructor(name:string){
        this.name=name
    }
    eatFood(){
        console.log(this.name+'吃粮食')
    }
}

var doggy=new Doggy('小白');
doggy.eatFood()//小白吃粮食

扩展接口

接口扩展:接口可以继承接口

interface AnimalDog{
    eatdog():void;
}

interface Fish extends AnimalDog{
    swim():void;
}

class Jinli implements Fish{
    public name:string;
    constructor(name:string){
        this.name=name
    }
    eatdog(): void {
       console.log(this.name+'喜欢吃饲料') 
    }
    swim() {
        console.log(this.name+'喜欢游泳')
    }
}

var fish=new Jinli('小鲤鱼');

fish.swim()//小鲤鱼喜欢游泳
fish.eatdog()//小鲤鱼喜欢吃饲料

更复杂的

interface AnimalDog{
    eatdog():void;
}

interface Fish extends AnimalDog{
    swim():void;
}

class BigShark {
    public name:string;
    constructor(name:string){
        this.name=name
    }
    eating(food:string){
        console.log((this.name+food))
    }
}

class SmallShark extends BigShark implements Fish{
    constructor(name:string){
        super(name)
    }
    eatdog(): void {
        console.log(this.name+'喜欢吃饲料') 
     }
    swim() {
        console.log(this.name+'喜欢游泳')
    }
}

var shark=new SmallShark('小黑');
shark.eating('吃肉肉')//小黑吃肉肉

6.泛型

  • 泛型:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
  • 在像c#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。这样用户就可以以自己的数据类型来使用组件。
  • 通俗理解:泛型就是解决类接口方法的复用性、以及对不特定数据类型的支持

泛型定义

需求:同时返回string类型和number类型

//只能返回string类型的数据
function getData(value:string):string{
    return value
}
// 同时返回string类型和number类型 (代码冗余)
function getData1(value:string):string{
    return value
}
function getData2(value:number):number{
    return value
}
// 同时返回string类型和number类型  any可以解决,但是放弃了类型检查
function getData(value:any):any{
    return value;
}

用泛型来实现需求

// 泛型:可以支持不特定的数据类型 要求:传入的参数和返回的参数一致
function getData<T>(value:T):T{
    return value
}

getData<number>(123);
getData<string>('七七');

泛型类

泛型类:有个最小堆算法,需要同时支持返回数字和字符串两种类型。通过泛型类来实现

class MinClass{
    public list:number[]=[];
    add(num:number){
        this.list.push(num)
    }
    min():number{
        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(21)
m.add(1)
m.add(11)
console.log(m.min())//1  这里只支持传入数字
//类的泛型
class MinClass<T>{
    public list:T[]=[];
    add(value:T):void{
        this.list.push(value)
    }
    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 m1 =new MinClass<number>();//实例化类,并且指定了类的T代表的类型是number
m1.add(12)
m1.add(1)
m1.add(14)
console.log(m1.min())//1

var m2 =new MinClass<string>();
m2.add('a')
m2.add('b')
m2.add('d')
console.log(m2.min())//a

泛型接口

// 函数接口
interface ConfigFn{
    (value1:string,value2:string):string;
}

var setData:ConfigFn=function (value1:string,value2:string):string{
    return value1+value2
}
setData('name','七七')
// 泛型接口
// 第一种
interface ConfigFn{
    <T>(value:T):T;
}
var getData:ConfigFn=function<T>(value:T):T{
    return value;
}
getData<string>('七七')
// 第二种
interface ConfigFn<T>{
    (value:T):T;
}
function getData<T>(value:T):T{
    return value;
}

var myGetData:ConfigFn<string>=getData;

myGetData('20')

把类作为参数的泛型

class User{
    username:string | undefined;
    password:string | undefined
}

class MysqlDb{
    add(user:User):boolean{
        console.log(user)
        return true
    }
}
var u=new User();
u.username='七七'
u.password='123456'

var db=new MysqlDb();
db.add(u)

如果这里不是对mysql数据库的账户和密码进行验证,换成对某个商品信息的验证,那么要对源码进行修改,工作量较大

//使用泛型修改
class User{
    username:string | undefined;
    password:string | undefined
}
//操作数据库的泛型类
class MysqlDb<T>{
    add(user:T):boolean{
        console.log(user)
        return true
    }
}
var u=new User();
u.username='七七'
u.password='123456'

var db=new MysqlDb<User>();
db.add(u)

常用封装

在这里插入图片描述

interface DBI<T>{
    add(info:T):boolean;
    update(infp:T,id:number):boolean;
    delete(id:number):boolean;
    get(id:number):any[];
}

//定义一个操作mysql数据库的类
class MysqlDB<T> implements DBI<T>{
    add(info: T): boolean {
        throw new Error("Method not implemented.");
    }
    update(infp: 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 Student{
    username:string | undefined;
    password:string | undefined;
}

var stu =new Student();
stu.username='七七';
stu.password='123456'


var oMysql=new MysqlDB<Student>();
oMysql.add(stu);

7.模块化

该部分和node.js类似
在这里插入图片描述
home.ts

export function getData():any[]{
    console.log('调用模块getData')
    return[
        {
            title:'xxxxx'
        },
        {
            title:'123456'
        }
    ]
}

function add(){
    console.log('add方法被调用!')
}

export default {add}//export default只能使用一次

index.ts

import { getData as get } from "./home";
get();

8.命名空间

namespace A{
export class dog{
	...
	eat(){}
}
namespace B{
export class dog{
}
}
var  d=new A.dog()
d.eat()
//命名空间的使用避免了大规模开发中出现的相同类名

命名空间也可以作为模块导出
在这里插入图片描述

9.装饰器

和java中的注解类似
在这里插入图片描述

类装饰器

类装饰器:在类声明之前被声明(紧靠着类声明)。装饰器应用于类构造函数,可以用来监视,修改或替换类定义,传入一个参数

类装饰器:普通装饰器(无法传参)

function logClass(params:any){
    console.log(params)
    //params 就是当前类
    params.prototype.apiUrl='动态扩展属性'

    params.prototypr.run=function(){
        console.log('我是一个run方法!')
    }
}
@logClass
class HttpClient{
    constructor(){

    }

    getData(){

    }
}

var http:any=new HttpClient()

console.log(http.apiUrl)
http.run()

类装饰器:装饰器工厂(可传参)

function logClass(params:string){
    return function(target:any){
        console.log(target)
        
        console.log(params)

        target.prototype.apiUrl=params
    }
}

@logClass('http://www.xxx.com/api')
class HttpClient{
    constructor(){

    }
    getData(){

    }
}

var http:any=new HttpClient()
console.log(http.apiUrl)//http://www.xxx.com/api

function logClass(target:any){
    console.log(target)

    
    return class extends target{
        apiUrl:any="修改后的数据"

        getData(){
            console.log(this.apiUrl)
        }
    }
}

@logClass
class HttpClass{
    public apiUrl:string |undefined
    constructor(){
        this.apiUrl='构造函数里面的api'
    }

    getData(){
        console.log(this.apiUrl)
    }
}
var http=new HttpClass()
http.getData()//修改后的数据

属性装饰器

属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
2、成员的名字。

类装饰器
function logClass(params:string){
    return function(target:any){
        console.log(target)
        
        console.log(params)

        target.prototype.apiUrl=params
    }
}

//属性装饰器
function logProperty(params:any){
    return function(target:any,attr:any){
        console.log(target)
        console.log(attr)

        target[attr]=params
    }
}

@logClass('xxx')
class HttpClient{

    @logProperty('http://baidu.com')
    public url:any |undefined
    constructor(){

    }
    getData(){
        console.log(this.url)
    }
}

var http=new HttpClient()
http.getData()//http://baidu.com

方法装饰器

它会被应用到方法的属性描述符上,可以用来监视,修改或者替换方法定义。
方法装饰会在运行时传入下列3个参数:
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。 2、成员的名字。
3、成员的属性描述符。

//方法一
function logMethods(params:any){
    return function(target:any,methodName:any,desc:any){
        console.log(target)
        console.log(methodName)
        console.log(desc)

        target.apiUrl='xxx'
        target.run=function(){
            console.log('running!')
        }
    }
}
class HttpClient{
    public url:any |undefined
    constructor(){

    }
    @logMethods('http://baidu.com')
    getData(){
        console.log(this.url)
    }
}

var http:any=new HttpClient()
http.run()
//方法二
function logMethods(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((val)=>{
                return String(val);
            })
            console.log(args)
            oMethod.apply(this,args)
        }

    }
}


class HttpClient{
    public url:any |undefined
    constructor(){

    }
    @logMethods('http://baidu.com')
    getData(){
        console.log('aaa')
    }
}

var http:any=new HttpClient()
http.getData(123456,'xxx')
//['123456','xxx']
//aaa

方法参数装饰器

…(看不懂了。。)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你想学习 TypeScript,我推荐你查看引用中提到的一篇入门教程。这篇教程将带你一步步学习 TypeScript 的十四个入门知识点,并且提供了详细的内容大纲。教程会教你如何在系统中全局安装 TypeScript,可以使用 npm 或者 yarn 进行安装。TypeScriptJavaScript 的超集,它在 JavaScript基础上添加了可选的静态类型和基于类的面向对象编程特性。微软在 2012 年正式发布了 TypeScript,并且持续更新和维护了 8 年。因此学习 TypeScript 是非常有价值的,尤其对于前端开发人员来说,它已经成为一门必备的技能。所以如果你想学习 TypeScript,这个入门教程会是一个不错的起点。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [最全TypeScript 入门基础教程,看完就会](https://blog.csdn.net/qq_43623970/article/details/107067306)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [TypeScript入门教程](https://blog.csdn.net/SoSalty/article/details/129372440)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值