TypeScript语法

一、基础部分

1.安装和编译
npm install -g typescript
tsc helloword.ts
2.用VScode 自动编译 .ts

a. 创建tsconfig.json文件。 tsc --init 生成配置文件
b. 任务 - 运行任务,监视tsconfig.json

3.typescript 中的数据类型(ts新增类型校验,ts 代码必须指定类型)
  • 布尔类型(boolean)
    var flag:boolean=true;

  • 数字类型(number)
    var num:number=123;

  • 字符串类型 (string)

  • 数组类型(array)
    定义数组的两种方式
    a. var arr:number[]=[11,22,33,44] ----- b. var arr:Array<number>=[11,22,33] --- var arr:any[]=[123,'123']

  • 元祖类型(tuple)属于数组的一种,为数组每一个位置指定一个类型
    let arr:[number,string]=[12,'aa']; let arr:Array<number,string>=[12,'string']

  • 枚举类型(enum)

enum Err {'undefined'=-1,'null'=-2,'success'=1};
var e:Err=Err.sucess;
console.log(e) //打印出的为1(如果标识符没赋值,它的值就是下标)
  • 任意类型(any)
    var num:any=123;
  • null 和 undefined
    var num:number | null | undefined
  • void 类型
//当方法没有返回值时:
function run():void{
  console.log('run')
}

//当方法有返回值时:
function run():number {
  return 123;
}
  • never类型
var a:never;
a=(()=>{
  throw new Error('错误');
})()
4. 函数的定义
//函数声明法
function run():string{
  return 'run';
}
//匿名函数法
var fun2=function():number{
  return 123;
}
//定义方法传参
function getInfo(name:string,age:number):string{
  return `${name}--${age}`;
}
//配置可选参数(用?)
function getInfo(name:string,age?:number):string{
  return ''
}
getInfo('zhangsan');
//三点运算符,接收传过来的值 
function sum(...result:number[]):number{
  var sum=0;
  for(var i=0;i<result.length;i++){
    sum+=result[i]
  }
}
//ts中方法的重载
function getInfo(name:string):string;
function getInfo(name:number):number;
function getInfo(str:any):any{
  if(typeof str==='string'){
    return ''
  }else{
  return '123'
}
ts中的类
class Person(){
  name:string; //属性,前边省略 了public关键词
  constructor(n:string){
     this.name=n;
  }
  run():void{
    alert(this.name)
  } 
}

class Person(){
  name:string; //属性,前边省略 了public关键词
  constructor(n:string){
     this.name=n;
  }
  getName():string{
    return this.name;
  } 
  setName(name:string):void{
    this.name=name;
  }
}
ts中的继承
class Person(){    
  public name:string; //公有属性
  constructor(name:string){
     this.name=name;
  }
 run():string{
    return `${this.name}在运动 `
  } 
}

class Web extends Person{
  constructor(name:string){
    super(name); //初始化父类的构造函数
  }
}

var w=new Web('李四');
alert(w.run();
类里面的修饰符,ts提供了三种修饰符
  • public:公有,内外部都可以访问
  • protected:保护类型 类内部、子类内部可以访问,类外无法访问
  • private:私有 在类内可以访问,子类无法访问。
    属性如果不加修饰符,默认为public
静态方法和静态属性
function Person(){
  this.run1=function(){} //实例方法,new之后才能用
}
Person.run2(); //静态方法,可以直接用。

class Person(){
  public name:string;
  public age:number=20;
  static sex="男";//静态属性
  constructor(name:string){
    this.name=name;
  }
  run(){ //实例方法
    alert()
  }
  static print(){
    console.log('print'+this.age) //会出错,静态没法不能直接调用类里的属性
    console.log('print'+Person.sex) //不会出错
  } //静态方法
}
多态:父类定义一个方法,不去实现。让继承它的子类去实现,每个子类有不同的表现。

比如先定义个ainimal类,里面有eat方法。然后有猫和狗两个子类去继承这个类,然后重写eat的方法。

抽象类:提供其他类继承的基类,不能直接被实例化。
用abstract 关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。

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

abstract class Animal{
  public name:string;
  constructor(name:string){
    this.name=name;
  }
  abstract eat():any;
}
var a=new Animal() //错误写法,抽象类不能直接被实例化。只能给其他类提供基类。
class Dog extends Animal{
  constructor(name:any){
    super(name);
  }
  //抽象类的子类必须实现抽象类中的抽象方法
  eat(){
    console.log('dog)
  }
}

接口的作用:在面向对象的编程中,它定义了行为和动作的规范,起到限制和规范的作用。它不关心类的内部状态数据和类里方法的实现细节,只规定这批类里必须提供某些方法。ts中的接口类似java,还增加了更多 接口类型,包括属性函数可索引和类等。

  • 属性接口 对json的规范。
function printLabel(labelInfo:{label:string}):void(){
  console.log(' ')
}
printLabel({name:'zhangsan'}) //错误
printLabel({label:'zhangsan'}) //正确
  • 属性类型接口
interface FullName{ //对传入对象的约束   (属性接口)
  firstName:string;
  secondName:string;
}

function printName(name:FullName){

}

实例: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){
      config.log('success');
  }
  }
}

ajax({
  tyle:'get',
  url:'http://www.baidu.com,
  data:{},
  dataType:'JSONP' 
 })
  • 函数类型接口 (对方法传入的参数以及返回值进行约束 )
interface encrypt{
  (key:string,value:string):string;
}

var md5:encrypt=function(key:string,value:string):string{
  return key+value;
}
  • 可索引接口:数组、对象的约束(不常用)
var arr:number[]=[123,123]
var arr1:Array<string>=['123','123']
 
interface UserArr{
  [index:number]:string
}

var arr:UserArr=['aaa','bbb'];
console.log(arr[0 ])
  • 类类型的接口(对类的约束)
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 + '');
  }
}

var d= new Dog();
  • 接口的扩展:接口可以继承接口
interface Animal{
  eat():void;
}
interface Person extends Animal{
  work():void;
}
class Programmer{
  public name:string;
  constructor(name:string){
    this.name=name;
    constructor(name:string){
      this.name=name;
    }
    coding(code:string){
      console.log('写代码')
    }
  }
}
class Web extends Programmer implements Person{
  public name:string;
  constructor(name:string){
    super(name)
  }
  eat(){
    console.log()
  }
  work(){
    console.log()
  }
}

--- ts中的泛型:就是解决类、接口、方法的复用性、以及对不特定数据类型的支持 ,传入和返回类型一致
T表示泛型,具体什么类型是调用方法的时候决定的

function getData<T>(value:T):T{
  return value;
}
getData<number>(123)

class MinCla<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 MinClas<number>(); //实例化类 并制定了类的T代表的类型是number;

var m2=new MinClas<string>(); //实例化类 并制定了类的T代表的类型是number;
  • 泛型接口
interface ConfigFn{
  <T>(value:T):T;
}

var getData:ConfigFn=function<T>(value:T):T{
  return value;
}

getData<string>('zhangsan');
getData<string>(123); //错误

  • 装饰器

装饰器是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。
常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器

  1. 类装饰器:在类声明前被声明(紧靠着类),可以用来监视修改或替换类。传入一个参数。
function logClass(params:any){
  console.log(params) //params 就是当前类
  params.prototype.apiUrl='aaaa';
  params.prototype.run=function(){
    console.log('我是一个run方法')
  }
}
@logClass
class HttpClient{
  constructor(){
    
  }
  getData(){
    
  }
}  
var http:any=new HttpClient();
console.log(http.apiUrl) // aaaa
http.run();

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

function logClass(params:string){
  return function(target:any){
    console.log(target); // 当前类
    console.log(params); //hello
    target.prototype.apiUrl=params;
  }
}
@logClass('hello')
class HttpClient{
  constructor(){
    
  }
  getData(){
    
  }
}  
var http:any=new HttpClient();
console.log(http.apiUrl) // aaaa

1.3. 类装饰器,重载构造函数的例子

function logClass(target:any){
    console.log(target);
    return class extends target{
      apiUrl:any='我是修改后的值';
      getData(){
        apiUrl=this.apiUrl+'111'
      }
    }
}
@logClass('hello')
class HttpClient{
  constructor(){
    
  }
  getData(){
    
  }
}  
var http:any=new HttpClient();
console.log(http.apiUrl) // aaaa
http.run();

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

function logClass(params:string){ //类装饰器
  return function(target:any){
    console.log(target); // 当前类
    console.log(params); //hello
  }
}

//属性装饰器
function logProperty(params:any){
  return function(target:any,attr:any){
    console.log(target);
    console.log(attr);
    target.attr=params;
  }
}
@logClass('hello')
class HttpClient{ 
  @logProperty('http:itying.com')
  public url:any | undefined;
  constructor(){
    
  }
  getData(){
    console.log(this.url);
  }
}  
var http:any=new HttpClient();
console.log(http.apiUrl) // aaaa
http.run();

3.方法装饰器 - 会被应用到方法的属性描述符上,可以用来监视修改或者替换方法定义。

方法装饰器会在运行时传入下列三个参数
1.对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象。
2.成员的名字
3.成员的属性描述符。

function get(params:any){
  return function(target:any,methodName:any,desc:any){
    console.log(target); // 当前类
     console.log(methodName) //getNData
     console.log(desc.value) //getData方法
    //修改装饰器的方法 把所有参数改成string类型
    //保存当前方法
    var oMethod=desc.value;
    desc.value=function(...args:any[]){
      args=args.map((value)=>{
        return String(value)
      })
      oMethod.apply(this,args); //如果没这句,会覆盖getData方法。
    }
  }
}
class HttpClient{
  public url:any | undefined
  constructor(){
    
  }
  @get('http://dddd')
  getData(...args:any[]){
    console.log(this.url)
  }
}  
  • 装饰器 的执行顺序:
    属性 > 方法 > 方法参数 >类
    如果有多个,则从后向前执行
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容