typescript

typescript中的数据类型

  • 布尔类型(boolean)

  • 数字类型(number)

  • 字符串类型(string)

  • 数组类型(array)

    第一种定义数组的方式:let arr:number[]=[1,2,3,4,5]

    第二种定义数组的方式:let arr:Array<number>=[1,2,3,4,5]

  • 元组类型(tuple)

    let arr:[string,number,boolean]=["ts",3.18,true]相当于js中的var arr=["ts",3.18,true]

  • 枚举类型(enum)

    enum Flag {
    	success=1,error=-1
    }
    var f:Flag=Flag.success
    console.log(f)//1
    
    enum Color{
    	red,blue=5,orange
    }
    var a:Color=Color.red
    var b:Color=Color.blue
    var c:Color=Color.orange
    //枚举项没有赋值的话输出的是索引
    console.log(a) //0
    console.log(b) //5
    console.log(c) //6
    
  • 任意类型(any)

    var a:any=123;
    a="qwe";
    console.log(a); //qwe
    
  • void类型(一般用于定义方法时方法没有返回值)

    //方法没有返回值
    function run():void{
    	console.log("run");
    }
    run();
    
    //方法有返回值
    function run():number{
    	return 123;
    }
    run();
    
  • undefined和null(never类型的子类型)

    var num:number;
    console.log(num) //输出undefined 报错
    
    var num:undefined;
    console.log(num) //输出undefined 未报错
    
    //一个元素可能是number类型可能是null可能是undefined
    var num:number | null | undefined
    num=123;
    console.log(num) //123
    
  • never类型 (代表从不会出现的值)

    var a:never;
    a=(()=>{
    	throw new Error("异常");
    })()
    

typescript中的函数

ts中定义函数的方式

1.函数声明:
function run():string{
	 return "run"
}
2.函数表达式:
var fun1=function():number{
	return 123;
}

ts中定义函数传参

function getInfo(name:string,age:number):string{
	return `${name}---${age}`;
}
alert(getInfo("张三",20))
var getInfo=function(name:string,age:number):string{
	return `${name}---${age}`;
}
alert(getInfo("张三",20))

ts中函数可选参数(es5中函数的实参和形参可以不一样,但是ts中必须一样并且可选参数必须写到参数的最后面)

function getInfo(name:string,age?:number):string{
	if(age){
		return `${name}---${age}`;
	}else{
		return `${name}---年龄保密`;
	}	
}
alert(getInfo("张三")) //ts中不传age实参的话需要在age形参后面加个?(并且age形参必须写到参数最后面)

ts中函数的默认参数(es5里面没法设置默认参数,es6和ts中都可以设置默认参数)

function getInfo(name:string,age:number=20):string{
	if(age){
		return `${name}---${age}`;
	}else{
		return `${name}---年龄保密`;
	}	
}
alert(getInfo("张三")) //张三---20
alert(getInfo("张三",30)) //张三---30

ts中函数的剩余参数

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

ts中的重载(重载允许一个同名函数接受不同数量或类型的参数时,作出不同的处理)

function getInfo(name:string):string;
function getInfo(age:number):string;
function getInfo(str:any):any{
	if(typeof str==='string'){
		return "我叫"+str;
	}else{
	 	reurn "我年龄是"+str;
	}
}
alter(getInfo("张三")); //我叫张三
alter(getInfo(20)); //我年龄是20

ts中的箭头函数

let sum = (a: number, b: number): number => {  
	return a + b;  
}  
console.log(sum(20,30)); //50  

typescript中的类

定义类

class Person{
	name:string;
	constructor(name:string){
		this.name=name;
	}
	getName():string{
		return this.name;
	}
	setName(name:string):void{
		this.name=name;
	}
}
var p=new Person("张三");
alert(p.getName()); //张三
p.setName("李四");
alert(p.getName()); //李四

类的继承

class Person{
	name:string;
	constructor(name:string){
		this.name=name;
	}
	run():string{
		return `${this.name}在运动`
	}
}
class Student extends Person{
	constructor(name:string){
		super(name); //初始化父类的构造函数
	}
	//子类重写父类方法
	run():string{
		return `${this.name}在运动-子类`
	}
	//子类定义自己的方法
	work():void{
		alert(`${this.name}在工作)
	}
}
var s=new Student("张三");
alert(s.run()); //张三在运动-子类

类里面的修饰符

typescript里面定义属性的时候提供了三种修饰符

  • public:公有 在类里面、子类、类外面都可以访问
  • protected:保护类型 在类里面、子类都可以访问,在类外面无法访问
  • private:私有 只能在类里面访问,子类、类外面都无法访问

静态属性和静态方法

class Person{
	public name:string;
	public age:number=20;
	constructor(name:string){
		this.name=name;
	}
	static sex="男";
	//静态方法中无法直接调用类里面的非static属性,只能调用类里面的static属性
	static print(){
		alert("print方法"+Person.sex);
	}
}
alert(Person.sex);

多态(父类定义一个方法不去实现,让继承它的子类去实现,每一个子类有不同的表现)(多态属于继承)

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+"吃老鼠"
	}
}

抽象类

  • 抽象类是提供其他类继承的基类,不能直接被实例化

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

  • 抽象方法只能放在抽象类中

    abstract class Animal{
    	public name:string;
    	constructor(name:string){
    		this.name=name;
    	}
    	abstract eat():any;
    	run(){
    		console.log("跑的方法");
    	}
    }
    class Dog extends Animal{
    	constructor(name:any){
    		super(name)
    	}
        //抽象类的子类必须实现抽象类中的抽象方法,非抽象方法可以不实现
    	eat(){
    		return this.name+"吃骨头"
    	}
    }
    var d=new Dog("小黑");
    d.eat();
    

typescript中的接口

接口的作用:在面向对象编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计中,接口起到了一种限制和规范的作用

  • 属性接口

    interface FullName{
    	firstName:string;
    	secondName:string;
    }
    function printName(name:FullName){
    	console.log(name.firstName+"--"+name.secondName)
    }
    //传入的参数必须包含firstName、secondName
    var obj={
    	firstName:"张",
    	secondName:"三",
    	age:20
    }
    printName(obj)
    
  • 可选属性接口

    interface FullName{
    	firstName:string;
    	secondName?:string;
    }
    function printName(name:FullName){
    	console.log(name)
    }
    printName({
    	firstName:"张"
    })
    
  • 函数类型接口(对函数传入的参数以及返回值进行约束)

    //加密的函数类型接口
    interface encrypt{
    	(key:string,value:string):string;
    }
    var md5:encrypt=function(key:string,value:string):string{
    	//模拟操作
    	return key+value;
    }
    console.log(md5("name","张三"));
    
  • 可索引接口(对数组、对象的约束)

    //对数组的约束
    interface UserArr{
    	[index:number]:string
    }
    var arr:UserArr=["aaa","bbb"];
    console.log(arr[0]); 
    //对对象的约束
    interface UserObj{
    	[index:string]:string
    }
    var arr:UserObj={
    	name:"张三"
    }
    
  • 类类型接口(对类的约束和抽象类有点相似)

    interface Animal{
    	name:string;
    	eat(str:string):void;
    }
    class Dog implements Animal{
    	name:string;
    	constructor(name:string){
    		this.name=name;
    	}
    	eat(food:string){
    		console.log(this.name+'吃'+food)
    	}
    }
    var d=new Dog("小黑");
    d.eat("骨头");
    
  • 接口扩展(接口可以继承接口)

    interface Animal{
    	eat():void;
    }
    interface Person extends Animal{
    	work():void;
    }
    class Student implements Person{
    	public name:string;
    	constructor(name:string){
    		this.name=name;
    	}
    	eat(){
    		console.log(this.name+"喜欢吃包子")
    	}
    	work(){
    		console.log(this.name+"写代码");
    	}
    }
    var s=new Student("小明");
    s.eat();
    s.work();
    

typescript中的泛型

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

//设计同时返回string类型和number类型
function getData1(value:number):number{
	return value;
}
function getData2(value:string):string{
	return value;
}
//可以看出使用这种方式明显代码冗余
function getData(value:any):any{
	return "哈哈哈";
}
//any可以解决代码冗余问题但是any放弃了类型检查,传入的参数类型和返回的参数类型可以不一致

解决以上问题的方法就是使用泛型

//T表示泛型,具体什么数据类型是调用这个方法时决定的
function getData<T>(value:T):T{
	return value;
}
getData<number>(123);
getData<string>("123");
  • 泛型类

    class Min<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 Min<number>();
    m1.add(3);
    m1.add(4);
    m1.add(1);
    alert(m1.min()) //1
    
    var m2=new Min<string>();
    m1.add("a");
    m1.add("b");
    m1.add("c");
    alert(m1.min()) //a
    
  • 把类作为参数类型的泛型类

    //操作数据库的泛型类
    class MysqlDb<T>{
    	add(info:T):boolean{
    		console.log(info);
    		return true;
    	}
    }
    //定义一个User类
    class User{
    	username:string|undefined;
    	password:string|undefined;
    }
    var u=new User();
    u.username="张三";
    u.password="123";
    //给User表增加数据
    var Db=new MysqlDb<User>();
    Db.add(u);
    
    //定义一个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;
    	}
    }
    var a=new ArticleCate({
    	title:"分类",
    	desc:"111"
    });
    //给ArticleCate表增加数据
    var Db=new MysqlDb<ArticleCate>();
    Db.add(a);
    
  • 泛型接口

    • 第一种定义泛型接口的方法
    interface ConfigFn{
    	<T>(value:T):T;
    }
    var getData:ConfigFn=function<T>(value:T):T{
    	return value;
    }
    getData<string>("张三");
    getData<number>(20);
    
    • 第二种定义泛型接口的方法
    interface ConfigFn<T>{
    	(value:T):T;
    }
    function getData<T>(value:T):T{
    	return value;
    }
    var myGetData1:ConfigFn<string>=getData;
    myGetData1("张三");
    var myGetData2:ConfigFn<number>=getData;
    myGetData2(20);
    

ts封装统一操作数据库的底层类库

  • 功能:定义一个操作数据库的库,支持Mysql、Mssql等数据库
  • 要求Mysql、Mssql功能一样,都有add、update、delete、get方法
  • 注意:约束统一的规范、以及代码重用
  • 解决方案
    • 约束统一的规范需要用到接口
    • 代码重用需要用到泛型

ts中的命名空间

命名空间:在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、类、接口等放置到命名空间内

//animal.ts
export namespace A{
	interface Animal{
		name:string;
		eat(str:string):void;
	}
	export class Dog implements Animal{
		name:string;
		constructor(name:string){
			this.name=name;
		}
		eat(food:string){
			console.log(this.name+'吃'+food)
		}
	}
}
//index.ts
import {A} from './modules/animal';
var d=new A.Dog("小黑");
d.eat("骨头")

ts中的装饰器

装饰器:是一种特殊类型的声明,它能够被附加到类、属性、方法或参数上,可以修改类的行为。通俗的讲装饰器就是一个方法,可以注入到类、属性、方法或参数上来扩展类、属性、方法或参数的功能

装饰器写法:普通装饰器(无法传参)、装饰器工厂(可传参)

常见装饰器:类装饰器、方法装饰器、属性装饰器、参数装饰器

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

    function logClass(params:any){
    	//params就是当前类
    	console.log(params);
    	params.prototype.apiUrl="动态扩展的属性";
    	params.prototype.run=function(){
    		console.log("我是一个run方法");
    	}
    }
    @logClass
    class HttpClient{
    	constructor(){
    	}
    	getData(){
    	}
    }
    var http:any=new HttpClient();
    console.log(http.apiUrl);
    console.log(http.run());
    
  • 类装饰器——装饰器工厂(可传参)

    function logClass(params:string){
    	return function(target:any){
    		//params就是http://www.itying.com/api
    		console.log(params);
    		//target就是HttpClient这个类
    		console.log(target);
    		params.prototype.apiUrl=params;
    	}
    }
    @logClass("http://www.itying.com/api")
    class HttpClient{
    	constructor(){
    	}
    	getData(){
    	}
    }
    var http:any=new HttpClient();
    console.log(http.apiUrl);
    
  • 类装饰器——应用于构造函数

    function logClass(target:any){
    	return class extends target{
    		apiUrl:any="我是修改后的apiUrl";
    		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();//我是修改后的apiUrl——
    
  • 属性装饰器

    function logProperty(params:any){
    	return function(target:any,attr:any){
    		//target就是HttpClient这个类的原型对象
    		console.log(target);
    		//attr就是url属性
    		console.log(attr);
    		target[attr]=params;
    	}
    }
    class HttpClient{
    	@logProperty("http://itying.com")
    	pulic url:any | undefined
    	constructor(){
    	}
    	getData(){
    		console.log(this.url);
    	}
    }
    var http=new HttpClient();
    http.getData();
    
  • 方法装饰器(它会被应用到方法的属性描述符上,可以用来监视,修改或替换方法定义)

    方法装饰器会在运行时传入3个参数:

    • 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
    • 方法的名字
    • 方法的属性描述符
    function get(params:any){
    	return function(target:any,methodName:any,desc:any){
    		//target就是HttpClient这个类的原型对象
    		console.log(target);
    		//methodName就是getData方法的名字
    		console.log(methodName);
    		console.log(desc);
    	}
    }
    class HttpClient{
    	pulic url:any | undefined
    	constructor(){
    	}
    	@get("http://www.itying.com")
    	getData(){
    		console.log(this.url);
    	}
    }
    
  • 方法参数装饰器

    参数装饰器会在运行时被当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据

    参数装饰器会在运行时传入3个参数:

    • 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
    • 方法的名字
    • 参数在函数参数列表中的索引
    function logParams(params:any){
    	return function(target:any,methodName:any,paramsIndex:any){
    		console.log(params);//id
    		//target就是HttpClient这个类的原型对象
    		console.log(target);
    		//methodName就是getData方法的名字
    		console.log(methodName);
    		//paramsIndex就是参数在函数参数列表中的索引
    		console.log(paramsIndex);
    	}
    }
    class logParams{
    	pulic url:any | undefined
    	constructor(){
    	}
    	getData(@logParams("id") uid:any){
    		console.log(uid);//123
    	}
    }
    var http=new logParams();
    http.getDta(123);
    
  • 装饰器执行顺序

    属性>方法>方法参数>类(如果有多个同样的装饰器,它会先执行后面的)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值