TypeScript语法入门

简介

  • 微软开发的自由和开源的编程语言

  • JavaScript 的一个超集支持 ECMAScript 6(ES6) 标准

  • 设计目标是开发大型应用,可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。

TS特性

TS是对JS一种扩展,增加的功能包括:

  • 类型批注和编译时类型检查
  • 类型推断
  • 类型擦除
  • 接口
  • 枚举
  • Minxin
  • 范型编程
  • 名字空间
  • 元祖
  • Await

以下功能是从ES6反向移植而来:

  • 模块
  • lambda函数的箭头语法
  • 可选参数及默认参数

TS与JS区别

  • TS是JS的超集,扩展了JS语法,因此JS可与TS一起工作无需任何修改;
  • TS通过类型注解提供编译时的静态类型检查
  • TS可处理已有的JS代码,并只对其中的TS代码进行编译;

TypeScript安装

如果你的本地环境已经安装了 npm 工具,可以使用以下命令来安装

npm install -g typescript

安装完成后我们可以使用 tsc 命令来执行 TypeScript 的相关代码,以下是查看版本号:

$ tsc -v
Version 3.8.3

开发工具

很多IDE都支持TypeScript插件,如:Visual StudioSublime Text2WebStormPHPStormEclipse

基础语法

TypeScript 程序由以下几个部分组成

  • 模块
  • 函数
  • 变量
  • 语句和表达式
  • 注释

第一个typeScript程序

  1. 编写我们ts文件(index.ts),通常我们使用 .ts 作为 TypeScript 代码文件的扩展名

    {
      const name: string = 'Tom';
      console.log(name);
      function fun1(name: string, age: number) {
        console.log(name, age);
      }
      fun1('Judy', 20);
    }
    
  2. 进入我们编写的ts文件目录执行如下命令进行编译

    #编译index.ts文件
    tsc index.ts
    

    此时我们可以看到生成对应的js文件
    在这里插入图片描述
    查看对应的index.js文件

    {
      var name_1 = 'Tom';
      console.log(name_1);
      function fun1(name, age) {
        console.log(name, age);
      }
      fun1('Judy', 20);
    }
    
  3. 执行js脚本运行

    node index.js
    Tom
    Judy 20
    
  4. TypeScript转换为JavaScript过程如下图
    在这里插入图片描述

我们可以同时编译多个ts文件

tsc file1.ts file2.ts file3.ts

TypeScript 关键字

breakascatchswitch
caseifthrowelse
varnumberstringget
moduletypeinstanceoftypeof
publicprivateenumexport
finallyforwhilevoid
nullsuperthisnew
inreturntruefalse
anyextendsstaticlet
packageimplementsinterfacefunction
newtryyieldconst
continuedo

TS语法注意

  1. 会忽略空白、换行、制表符
  2. 区分大小写
  3. 分号可选(建议使用)但是同一行多条语一定要用分号来分隔

TypeScript 注释

TS支持两种类型注视

  • 单行注释//
  • 多行注释: /**/
//这是一个单行注释

/*
 这是一个多行注释
 这是一个多行注释
 这是一个多行注释
 */

TypeScript与面向对象

TS是一种面向对象的编程语言,因此对象可抽象为其中包含属性方法

我们定义一个类

//定义类
class Person {
  //声明属性
  name: string = 'zcmain';
  //声明方法
  getName(): string {
    return this.name;
  }
}

//通过关键字new实例化Person对象(类)
const person = new Person();
//调用该对象的getName()方法
console.log(person.getName());
//zcmain

TypeScript变量声明

TS变量命名规则

  • 变量名称可以包含数字和字母,除了_$以外不能包含其他特殊字符,包括空格;
  • 变量名不能以数字开头;

声明格式

var [变量名]:[变量类型]=[变量初始值];

  • 声明变量,并设置初始值

    var name:string = 'Tom';
    //name = Tom
    
  • 声明变量,不设置初始值(初始值默认为undefined)

    let name:string;
    //name = undefined;
    
  • 声明变量,设置初始值,但不设置类型(默认为初始值类型)

    let a = 'zcmain'
    a= 20;    //错误!变量a只能是string类型
    
  • 声明变量,不设置类型和初始值(类型默认为任意类型any)

    let a;
    a = 20;
    a = 'zcmain';
    

TypeScript变量作用域

TS中变量有以下几种作用域

  • 全局作用域:全局变量定义在程序结构外部,它可以在代码任何位置使用
  • 类作用域:变量定义在类内部方法的外边,也可称为字段,可通过类对象访问,类静态变量可通过类直接访问
  • 局部作用域:变量定义在代码块(如:方法中)中使用
var global_num = 20//全局变量——全局作用域
class Person{
   var name:string='Tom';    //实例变量——类作用域
   static age:number = 20;   //静态变量
   
   todo(){
     var name:string;        //局部变量
   }
}

TypeScript基础类型

TS数据类型包含如下:

anynumberstringboolean数组元组枚举voidnullundefinednever

any

任意类型,可赋予任意类型的值,任意类型会在编译时跳过检查!

number

数值类型,双精度64位浮点值,可表示整数和分数

Number

是原始数值(number)的包装对象,该对象支持属性如下:

  • 属性

    1. MAX_VALUE:可表示最大的数。
    2. MIN_VALUE:可表示最小的数,最接近0的正数。
    3. NaN:非数字值。
    4. NEGATIVE_INFINITY:负无穷大,溢出时返回该值,该值小于MIN_VALUE。
    5. POSITIVE_INFINITY:正无穷大,溢出时返回该值,该值大于MAX_VALUE。
    6. prototype:Number对象的静态属性,使您有能力向该对象添加属性和方法。
    7. constructor:返回创建此对象的Number函数的引用。
    console.log('TypeScript Number对象属性:');
    console.log('最大值',Number.MAX_VALUE);
    console.log('最小值',Number.MIN_VALUE);
    console.log('正无穷大',Number.POSITIVE_INFINITY);
    console.log('负无穷大',Number.NEGATIVE_INFINITY);
    //输出
    TypeScript Number对象属性:
    最大值 1.7976931348623157e+308
    最小值 5e-324
    正无穷大 Infinity
    负无穷大 -Infinity
    
  • 方法

    1. toExponential(int):将数值转换为指数计数法(指定保留小数位长度)
    2. toFixed(int):把数值转换为字符串(指定小数位数)
    3. toPrecision(int):把数值格式化为指定长度字符串(指定字符串长度)。
    4. toString(int):把数值转换为指定进制的字符串,如果省略参数,则默认使用基数10,(基数:2~36之间整数);

string

字符串类型,用单引号('')或双引号("")表示,反引号(`` ` )用来定义多行文本和内嵌表达式。

let name:string = 'zcmain';
let age:number = 20;
let str:string = `您好,我叫 ${name},     
今年 ${age}岁!`;
console.log(str);
//您好,我叫 zcmain,
//   今年 20岁!

boolean

布尔类型,表示逻辑true和false。

数组类型

声明变量为数组。在元素类型后加上[]

let ages:number[]= [1,2,3,4];
let names:string[] = ['Tom','Judy','Zcmain'];
//或者使用泛型数组
let ages:Array<number> = [1,2,3];
let names:Array<string> =['Tom','Judy','Zcmain'];

//任意类型的数组
let arr:any[] = [1,'Tom',false,()=>{},{name:'Tom',age:2}];
console.log(arr[3]);  //[Function]
  • 通过Array对象创建数组

    指定数组初始化大小

    let arr = new Array(4);
    arr[0] = 'a';
    arr[1] = 'b';
    arr[2] = 'c';
    arr[3] = 'd';
    

    直接初始化数组元素

    let arr = new Array('a','b','c','d');
    //或者简化实例化
    let arr =['a','b','c','d'];
    
  • 通过ES6的Array.of()初始化数组

    在ES6之前比如我们想通过new Array()方式创建仅有一个元素的数组,是行不通的

    //如上,我想通过new Array创建一个是有一个元素3的数组,此时会生成一个大小为3且每项都为empty的数组
    let array = new Array(3);
    //[empty,empty,empty]
    
    //此时我们可通过ES6提供的Array.of实现
    let array = Array.of(3);
    //[3]
    
  • 数组常用方法

    • concat(…arrs):数组连接,返回一个新数组。

      let arr1 = [1,2,3];
      let arr2 = [4,5,6];
      let arr3 = ['a','b','c'];
      let arr = arr1.concat(arr2,arr3);
      //arr = [1,2,3,4,5,6,'a','b','c']
      
    • every(function)/some(function):检测数组每个/某个元素是否符合指定的要求,返回布尔类型

      let arr = [5,8,2,4];
      function isBigEnough(value, index, array){
        return value>5;
      }
      let isTrue = arr.every(isBigEnough);  
      //isTrue = false   //数组中是否每个值都大于5
      
      
      function isBigEnough2(value, index, array){
        return value>5;
      }
      let isTrue2 = arr.some(isBigEnough);  
      //isTrue2 = true   //数组中有元素的值大于5
      
      
      
    • filter(function):对数组元素进行指定条件过滤,返回满足条件的元素的数组

      let arr = [5,8,2,4];
      function isBigEnough(value, index, array){
        return value>=5;
      }
      let arr2 = arr.filter(isBigEnough);  
      //arr2 = [5,8]
      
    • forEach(function):对数组进行遍历

      let arr = [1,2,3,4];
      arr.forEach(function(value){
      	console.log(value);
      });
      //1
      //2
      //3
      //4
      
    • indexOf(element):指定元素查询数组中,首次出现的位置(下标)

      let arr = [1,2,3,4,3];
      let index = arr.indexOf(3);
      //index = 2   元素3首次出现在数组中下标为2的位置
      
    • lastIndexOf():指定元素查询数组中,最后出现的位置(下标)

      let arr = [1,2,3,4,3];
      let index = arr.lastIndexOf(3);
      //index = 4   元素3最后出现在数组中下标为4的位置
      
    • map(function):指定函数对数组中每个元素处理,返回新元素组成的数组

      let arr = [1,2,3,4];
      let arr2 = arr.map(function(value)=>{
           return value*2;
       });
      //arr2 = [2,4,6,8]
      
    • pop()/shift():删除并返回数组中最后一个/第一个元素

      let arr = [1,2,3,4];
      let num = arr.pop();
      //num = 4   删除了arr数组中最后一个元素4
      
      let num2 = arr.shift();
      //num2 = 1  删除了arr数组中第一个元素
      
    • unshift(…element):向数组头添加一个或多个元素,并返回数组长度

      let arr = [1,2,3,4];
      let length = arr.unshift('a','b','c');
      //length = 3
      //arr = ['a','b','c',1,2,3,4]
      
    • push(…element):像数组末尾添加一个或多个元素,并返回数组最新长度

      let arr = [1,2,3,4];
      let length = arr.push(5,6,7);
      //length = 7                //数组长度为7
      //arr = [1,2,3,4,5,6,7]     //数组元素
      
    • splice(start, number,element):从数组的指定位置删除或者添加元素,返回修改数量

      • Start:要操作数组的开始位置(下标)
      • number:要删除元素的个数(如果是添加则为0)
      • element:要添加的元素,如果是删除则不写
      let arr:any[] = [1,2,3,4];
      //在数组arr下标为2位置添加a元素
      let number = arr.splice(2,0,'a');
      //number = 1           
      //arr = [1,2,'a',3,4]
      
      //删除数组arr下标为0开始2个元素
      let removeNumber = arr.splice(0,2);
      //removeNumber = 2
      //arr = [ 'a', 3, 4 ]
      
    • reduce()/reduceRight():计算数组中所有元素的数值(从左到右/从右到左)

      let arr = [1,2,3,4];
      let sum = arr.reduce();
      //sum = 10
      
    • sort():对数组进行排序

      let arr = [6,2,8,4,0];
      let arr2 = arr.sort();
      //arr2 = [ 0, 2, 4, 6, 8 ]
      
      let arr3 = ['Tom','Judy','Susan'];
      let arr4 = arr3.sort();
      //arr4 = [ 'Judy', 'Susan', 'Tom']
      
    • toString():将数组转换成字符串返回

      let arr = [1,2,3,4];
      let str = arr.toString();
      //str = 1,2,3,4
      

元组

一般我们的数组元素都是相同的(any[]数组除外),如果存储的元素数据类型不同,则需要使用元组

已知元素数量和类型的数组,各元素类型不必相同,对应位置类型需要相同!

//声明变量x为元祖类型(固定的元素数量和指定类型)
let user:[string,number,boolean,any];
user = ['Tom',20,false,'我叫Tom,今年20岁,目前还未毕业'];
console.log(x[1]);  //20

user = ['Tom',20,false,];      //错误,元组元素个数与声明的个数不匹配
user = [20,'zcmain',false,30]; //错误,元组元素类型与定义对应类型不同

枚举

枚举用于定义**数值**集合

注意:

  1. 默认情况下,枚举是基于 0 的,也就是说第一个值是 0,后面的值依次递增
  2. 可以向枚举传递一个值,然后获取对应的名称值
  3. 枚举值除了设置数值,还可以设置字符串,但是不推荐设置字符串

枚举不设置值,枚举值默认是从0递增

//定义Color枚举
enum Color{Red,Blue,Green}

//声明变量c为Color枚举类型
let a:Color = Color.Red;
let b:Color = Color.Green;

console.log(a);  //0,枚举未添加方法,枚举值是从0开始的有序数值(下标)
console.log(b);  //2

手动设置枚举值(尽量不要为多个枚举项手动设置值,容易值冲突)

enum Color{
  Red=2,
  Blue
  Green}
//声明变量c为枚举Color类型
let c:Color = Color.Blue;
console.log(c);  //3

//手动设置多个枚举项值(Green 与 Yellow项值都是4),因此建议不要设置多个枚举项值
enum Color{
  Red = 1,
  Blue,
  Green,       //4
  Yellow = 4,  //4
  White,
}

获取枚举值及对应名称值

//声明Color枚举类型
enum Color{
    Red,
    Blue,
    Green,
    White,
    Yellow,
}
//获取枚举项值
Color.Red;     //0
Color.Green;   //2
Color.Yellow;  //4

//获取枚举项名称
Color[Color.Red];     //Red
Color[Color.Green];   //Green
Color[Color.Yellow];  //Yellow

void

用于标示返回值类型,表示该方法没有返回值

//函数无返回值
setName(name:string):void{
	this.name = name;
}
//无返回值可省略void
setName(name:stirng){
  this.name = name;
}
  • null:null是一个只有一个值的特殊类型,表示一个空对象的引用,用typeof检测null返回是object。
  • undefined:是一个没有设置值的变量,用typeof检测返回undefined。
  • never:never是其他类型(包括null和undefined)的字类型,代表从不会出现的值。

如果一个变量支持多种类型可用|隔开

//声明person变量,类型可以为字符串、或者数值、或者null
let person: string | number | null;

person = 'zcmian';  //正确
person = 20;				//正确
person = null;			//正确
person = false;     //错误!person不可为boolean类型

TypeScript联合类型

联合类型可以通过(|)符号将变量设置支持多种类型,赋值可根据设置类型来注意:只能赋值指定的联合类型中支持的,如果不在联合类型范围内将出错。

语法格式

let var:Type1|Type2|Type3

实例

//声明变量person类型为联合类型(支持number、string类型)
let person:number|string;
person = 20;     
person = 'Tom';
person = false;   //错误!person联合类型中不支持boolean类型

数组联合类型

我们也可以将数组声明为联合类型

//声明数组变量arr,类型为数组联合类型(联合类型=数值数组和字符串数组)
let arr:number[]|string[];
//数组赋值(值只能为联合类型支持的)
arr = [1,2,3,'a','b'];
arr = [1,2,3,'a','b',false];  //错误!数组联合类型不支持boolean

TypeScript循环语句

循环语句允许我们多次执行一个语句或语句组,TS中循环分为:

for

let array:Array<any> = [1,2,'a',false];
for(let i = 0;i<array.length;i++){
    console.log(i,array[i]);
}
//0,1
//1,2
//2,a
//3,false

for…in等价于for

该语句用于一组值的集合或列表迭代输出.

let array:Array<any> = [1,2,'a',false];
for(let index in array){
  console.log(index,array[index]);
}
//0,1
//1,2
//2,a
//3,false

for…of

此外TypeScript还支持for...offorEacheverysome循环

在 ES6 中引入的 for…of 循环,以替代 for…in 和 forEach() ,并支持新的迭代协议,for…of 允许你遍历 Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等可迭代的数据结构等。

forEach、every 和 some 是 JavaScript 的循环语法,TypeScript 作为 JavaScript 的语法超集,当然默认也是支持的。

while

do…while

TypeScript函数

函数就是包裹在花括号{}内的代码块,前面使用function关键字,

函数格式

function funName(param1 [:datatype], param2 [:datatype]):return_type{  
   //执行代码块 
  return value;
}
  • funName:函数名称,省略则为匿名函数
  • param:函数参数
  • datatype:参数类型
  • return_type:返回值类型
  • value:函数返回值。

实例

function add(a:number,b:number):number{
    return a+b;
}
//匿名函数(匿名函数入股需要供其他函数调用需要在定义时候赋值给一个变量)
let setName = function (name:string):void{
    this.name = name;
}


//匿名函数自调用
function (name:string,age:number){
  console.log('i am ${name},i m ${age} yeas old!')
}

函数的可选参数、默认参数、剩余参数

  • 可选参数

    在typescript函数里,如果定义了参数,则必须传入相对应参数,除非使用问好?标识符将参数设置为可选

    //函数add的c参数设置为可选参数
    function add(a:number,b:number,c?:number):number{
      if(c){
        return a+b+c;
       }else{
         return a+b;
       }
    }
    
    add(1,2,3);  //6
    add(1,2);    //3
    add(1);      //错误!函数add仅有一个是可选参数,其余参数必选
    
  • 默认参数

    我们也可以设置参数的默认值,如果调用函数不传入对应参数值,则函数使用默认值

    function add(a:number=1,b:number=5):number{
      return a+b;
    }
    
    add();       //6  函数两个参数都使用默认值
    add(2);      //7  函数b参数使用默认值
    add(10,20);  //30 函数参数不实用默认值
    
  • 剩余参数

    有时候我们不确定函数需要接受多少参数,这时候我们可使用省略号(...)定义函数函数为剩余参数,将不确定个数的参数放入到参数的数组汇中(参数下标从0开始)

    //函数add将第一个参数除外其他参数,放入到any类型的params数组中
    function add(a:number,...params:any[]):number{
        //指定获取剩余参数数组中指定位置的参数
        let param = params[1];     
        //遍历剩余参数数组
        forlet param of params){
          console.log(param);
        }
    }
    
    add(1,'a',false,{name:'Tom',age:20});
    //false    
    
    //a
    //false
    //{name:'Tom',age:20}
    

匿名函数

没有名字的函数,即为匿名函数。

我们可以将匿名函数赋值给一个变量供外部调用,或者使用小括号**()**包括起匿名函数然后对其自身调用。

  • 匿名函数赋值给一个变量

    //将匿名函数赋值给add变量
    let add = function (a:number,b:number):number{
    	return a+b;
    }
    //调用匿名函数
    console.log(add(2,6));  //6
    
  • 匿名函数自调用

    //1. 使用小括号包裹起匿名函数
    (function (name,age){
      console.log(`I am ${name},I'm ${age} years old!);
    })('Tom',20);  //2. 通过小括号对匿名函数自身调用
    
    //I am Tom,I'm 20 years old!
    

箭头函数(Lambda 函数)

Lambda函数也称之为箭头函数

  • 箭头函数格式

    ([param1, parma2,…param n]):return_type=>{
       //代码块
    }
    
  • 实例

    //普通函数
    let add1 = function (a:number,b:number):number{
    	return a+b;
    }
    //等价于下面箭头函数
    let add2 = (a:number:b:number):number=>{
      return a+b;
    }
    
    add1(1,2);   //3
    add2(1,2);   //3
    
  • 省略()和{}(仅在ES6以下标准有效)

    如果是单个参数可省略小括号;如果代码块仅有一行可省略花括号{}

    //普通函数
    let add1 = function (a:number){
    	return a;
    }
    
    //等价于下面箭头函数(ES5)
    let add2 = a=>return a;
    
    //在ES6模式下,必须指定参数类型,因此不能缺省小括号和大括号
    let add3 = (a:number)=>{return a};
    
  • 无参数时可设置空小括号()

    如果函数没有参数,可指定空小括号

    //普通函数
    let getName = function(){
      return this.name;
    }
    
    //等价于下面箭头函数
    let getName = ()=>{
      return this.name;
    }
    

方法重载

重载是子类相较于父类而言,方法名字相同,而参数不同(类型或数量及顺序),返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

  • 重载—参数类型不同

    function funName(a:number){};
    function funName(a:string){};
    
  • 重载-参数个数不同

    function funName(a:number);
    function funName(a:number,b:number);
    
  • 重载-参数顺序不同

    function funName(name:string,age:number){}
    function funName(age:number,name:string){}
    

PS

如果参数类型不同,则函数声明时参数类型应设置为 any

参数数量不同,则函数声明时可以将不同的参数设置为可选。

构造函数

typescript也支持内置的构造函数 Function() 来定义函数:

let res = new Function('...args','return xxx');

实例

let add = new Function("a","b","return a+b");
console.log(add(2,3));  // 5

TypeScript类(仅单继承)

TypeScript是面向对象的JavaScript,TS支持面向对象所有特定如:接口

类定义

class className{
    //类作用域
}

使用class关键字进行定义,后面紧跟类名,类包含以下几个模块(成员)

  • 字段:是类里面声明的变量,用来表示对象有关数据。
  • 构造函数:类实例化时候调用,为类对象分配内存。
  • 方法:方法是对象要执行的操作。

实例

//定义Person类
class Person{
    //类的字段
    name:string;
    age:number;
    //类的构造函数
    constructor(){
      this.name = 'Tom';
      this.age = 20;
    }
    //类的方法
    getInfo():string{
      return this.name + this.age;
    }
}

//实例化类 通过new 关键字
let person = new Person();
//调用类的方法
person.getInfo();  //Tom 20

类的继承

  • 使用extends关键字实现子类继承父类
  • 子类不能继承父类私有成员(方法和属性)和构造函数外,其他都可继承
  • 类的继承仅支持单继承,但支持多重继承(如:A继承B,B继承C,C继承D ,那么A具备BCD类属性和方法)

类继承格式

class className2 extends className1{
     //作用域
}

实例

//定义类A
class A{
    age:number = 0;
    serAge(age:number):void{
      this.age = age;
    }
}

//定义类B继承A类
class B extends A{
    name:string = '',
    setName(name:string):void{
      this.name = name;
    }
    getInfo():string{
      return this.name + this.age;   //B继承A,因此可访问父类A中的age属性
    }
}

let b = new B();
b.setName('Tom');
b.setAge(20);
b.getInfo();  //Tom 20

方法重写

类继承后,子类可重写父类的方法,其中super关键字是对父类的直接引用

class A{
  sayHello():void{
       console.log('Hello A ...');
  }
}

//B类继承A类
class B extends A {
    //重写A类sayHello方法
    sayHello(): void {
        super.sayHello();  //先调用父类的sayHello方法
        console.log('Hello B ...');
     }
}

let b = new B();
b.sayHello();  

//Hello A ...
//Hello B ...

static关键字

static关键字定义类的成员(属性或方法)为静态的,可以通过类名直接调用

class Person{
   //静态属性
   static age:number;
   static nickName:string;
   //实例属性
   address:string;
   
   constructor(){
     this.address = 'Beijing';
   }
  
   //静态方法
   static getInfo():string{
     return this.nickName + this.age
   }
  
  //实例方法
   getAddress():string{
     return this.address;
   }
}

//静态属性和方法,通过类名直接调用
Person.age = 20;
Person.name = 'Judy';
Person.getInfo();  //Judy 20

//实例属性和方法,需要实例化对象后方可调用
let person = new Person();
person.setAddress('ShangHai');
person.getAddress(); //ShangHai

instanceof运算符

instanceof用来判断对象是否是指定的类型,如果是返回true,否则返回false

class Person{}
class User{}
let isBoolean = false;

let person = new Person();
console.log(person instanceof Person);  //true
console.log(person instanceof User);    //false
console.log(isBoolean instance boolean); //true

访问控制修饰符

TS中,可以使用访问控制修饰符来保护类、方法、变量和构造方法的访问,TS支持三种不同的访问权限

  • public(默认):公有,可以在任何地方被访问
  • protected:受保护,可以在自身及其子类和父类中访问
  • private:私有,只有自身可访问。

类实现接口(implements

类可通过implements关键字实现接口,并将接口中字段作为属性使用,类需要实现接口中声明的方法

//定义接口
interface IPerson{
     name:string;
     getName():string;
}

//定义类实现接口
class Man implements IPerson{
      //接口中字段,可作为类属性使用
      name:string;
  
      //构造函数对属性进行初始化
      constructor(name:string){
        this.name = name;
      }
      
      //实现接口中方法
      getName():string{
        return this.name;
      }
}

let man = new Man('Judy');
man.getname();    //Judy

TypeScript接口(支持多继承)

接口是一系列抽象方法的声明,是对行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用,接口中抽象方法需要由具体的类去实现。

TypeScript接口格式

interface inteface_name{
      name:string;                 //属性
      age:number;
      setName(name:string):void;   //抽象方法,需要由具体的类去实现
}

TypeScript接口分类

在typescript接口中可分为:属性类型接口类类型接口函数类型接口可索引接口

属性类型接口

属性类型接口用来约束对象的属性(所属该接口对象,必须包含该接口内声明的所有非可选属性)

//声明属性接口,用来约束对象属性
interface IPerson{
 	name:string;
  age:number;
}

//定义Man对象,类型为IPerson接口类型,因此该对象只能包含IPerson接口内声明的属性,否则出错
let Man1:IPerson = {
  name:'Tom',
  age:20,
}
//Man1 = {name:'Tom',age:20}

//错误!!!对象属性不满足IPerson接口中声明的属性(缺失age属性,且多一个address属性)
let Man2:IPerson = {
  name:'Tom',
  address:'ShangHai',   
}

设置属性可选

通过?符号可设置可选属性

//声明属性接口,用来约束对象属性(其中age属性是可选的)
interface IPerson{
 	name:string;
  age?:number;    //通过'?'符号设置该属性可选
}

//声明Man1对象是IPerson类型,age属性可选择性实现
let Man1:IPerson = {
  	name = 'Tom',
}
//Man1 = {name:'Tom'} 
类类型接口

类类型接口用来约束类的属性和方法(实现该接口的类,必须包含该接口内非可选属性以及实现接口内抽象方法)

//1. 定义IPerson接口
interface IPerson {
   //属性
   name: string;
   age: number;
  //抽象方法(由具体类实现)
   getInfo(address: string): string;
}

//2. 定义Man类实现IPerson接口
class Man implements IPerson2 {
   //接口中声明的属性
   age: number;
   name: string;
   //构造方法中,对接口属性进行初始化(age参数设置默认值)
   constructor(name: string, age: number = 20) {
        this.name = name;
        this.age = age;
   }
   //实现接口中声明的抽象方法
   getInfo(city: string): string {
       return `I am ${this.name},I'm ${this.age} years old and I live in ${city}`;
   }
}

//实例化Man对象
let man = new Man('Judy');
console.log(man.getInfo('Beijing'));
//I am Judy,I'm 20 years old and I live in Beijing
函数类型接口

函数类型接口是约束函数的参数和返回值(所属该接口函数的参数和返回值必须满足该接口内对函数约束条件)

//1. 定义函数类型接口
interface IFunction{
   //对函数的参数和返回值进行约束
   (param1:string,param2:number):string;
}

//2. 声明一个函数,类型为上面定义的接口(函数参数和返回值必须满足IFunction接口内的约束,否则出错)
let func1:IFunction = function(name:string,age:number):string{
      return `${name},${age}`;
}

//func1也可使用箭头函数简化为
let func1:IFunction = (name:string,age:number):string=>{
   return `${name},${age}`;
}

//错误!!!函数参数和返回值不满足所属接口中对函数的约束条件(参数类型不匹配,且此函数无返回值)
let func2:IFuction = function(age:number,name:string){   
     console.log(name,age);
}
可索引类型接口

可索引类型接口用于约束数组和对象(不常用)

  • 约束数组
//声明数组接口,索引值为number类型,元素值为string类型
interface IArray{
   [index:number]:string;   
}
//定义数组arr1,类型为IArray
let arr1:IArray = ['Tom','Susan','Judy'];
console.log(arr1[0]);   //Tom           

let arr2:IArray = ['Tom',2,'Judy'];   //错误!!!数组arr2类型属于IArray,元素值只能是字符串
  • 约束对象
//声明对象接口,索引值为string类型,元素值为number类型
interface IObj{
    [index:string]:number;
}

let obj1:IObj = {age1:20,age2:30};
let obj2:IObj = {name:'Tom',age2:30};  //错误!!!对象Obj1类型为IObj,值只能为number类型

接口和联合类型

在接口中使用联合类型(用联合类型来对接口内的属性或函数参数及返回值)

//定义接口
interface IPerson{
    age:number;
    user:string|boolean;    //属性user为联合类型(字符串或布尔类型)
}

//定义Man1对象,类型为IPerson
let Man1:IPerson = {
    age:=26;
    user:='Judy';
}

//定义Man2对象,类型为IPerson
let Man2:IPerson = {
    age:30,
    user:=50;    //错误!!!user属性不满足IPerson中指定的联合类型
}

接口继承

接口可以继承其他接口来扩展自己,TypeScript允许接口继承多个接口

单继承接口
interface interfaceName2 extends interfaceName1{}
多继承接口
interface interfaceName3 extends interfaceName1,interfaceName2,...interfaceNameN{}
//声明接口1
interface IPerson1{
   age:number;
}
//声明接口2
interface IPerson2{
   name:string;
}
//声明接口3
interface IPerson3{
  setInfo(info:string):void;
}

//声明总接口,继承IPerson1、IPerson2、IPerson3
interface IPerson extends IPerson1,IPerson2,IPerson3{
   getInfo():string;
}

//定义PersonImpl类实现IPerson接口
class PersonImpl implements IPerson{
   //IPerson接口及其父接口中的属性
   age:number;
   name:string;
   //PersonImpl中定义的属性
   info:string='';
  
   //通过构造函数,对属性进行赋值
   constuctor(age:number,name:string){
     this.age = age;
     this.name = name;
   }
  
   //实现IPerson及其父接口中所有抽象方法
   setInfo(info:string):void{
     this.info = info;
   }
  
   //实现IPerson及其父接口中所有抽象方法
   getInfo():string{
       return `I am ${this.name},I'm ${this.age} years old and ${this.info}`;
   }
}

let personImpl = new PersonImpl(20,'Judy');
personImpl.setInfo('live in Beijing!');
personImpl.getInfo();
//I am Judy,I'm 20 years old and I live in Beijing

TypeScript对象

TS中对象是包含键值对的实例,值可以是标量、数组、对象等

对象实例

let person = {
    key1:'value1',   											  //值是标量
    key3:[element1,element2,...,elementN],  //值是数组
    key4:{name:'Tom',age:20},               //值是对象
    key5:()=>{															//值是函数
      console.log('function...')
    }
}

TypeScript 模块

TS中模块设计理念是可以跟换的组织代码。

模块特点
  • 模块在其自身作用域中执行,并不是在全局作用域

  • 模块内变量、函数、类等只在模块内有效,外部不可见,除非明确使用**export**导出。

  • 使用模块需要通过**import**关键字导入。

模块导入导出格式
  1. 定义接口并导出(IPerson.ts)

    //定义IPerson接口并导出
    export interface IPerson{
      	name:string;
        age:number;
        getInfo():string;
    }
    
  2. 定义Man实现类,实现IPerson接口并导出。(Man.ts)

    //导入IPeson模块
    import {IPerson} from './IPerson';
    export class Man implements IPeson{
        name:string='Tom';
        age:number=20;
        //实现IPerson接口的getInfo方法
        getInfo():string{
          return this.name + this.age;
        }
    }
    
  3. 在其他文件中使用Man对象

    //导入Man模块
    import {Man} form './Man';   
    //实例化 Man 对象
    let man = new Man();
    man.getInfo();     //Tom 20
    

TypeScript运算符

TS运算符与其他语言相似,这里不在介绍,大致分为:

  • 算数运算符

    加、减、乘、除、取余、自增、自减

    +-*/%++--

  • 关系运算符

    等于、不等于、大于、小于、大于等于、小于等于

    ==!=><>=<=

  • 逻辑运算符

    并且、或、取反

    &&||

  • 按位运算符

    按位与、按位或、取反、异或、左移、右移、五符号右移

    &~^<<>>>>>

  • 赋值运算符

    赋值、先加后赋值、先减后赋值、先乘后赋值、先除后赋值

    ==+=-=*=/=

    类似的逻辑运算符也可与赋值运算符联合使用

    左移后赋值、右移后赋值、按位与后赋值、按位或后赋值、异或后赋值、取反后赋值

    <<=>>=&=|=^=~=

  • 三元/条件运算符

    Test ? expr1 : expr2

  • 字符串运算符

    字符串链接符

    +

  • 类型运算符

    类型判断符

    typeof

    let name = 'zcmain';
    console.log(typeof name); //string
    

TypeScript 条件语句

TS中条件语句与其他语言类似,这里省略大概分为:

  • if
  • if…else
  • if…else if…esle
  • switch…case

扩展

1. 使用Typescript开发node.js项目——简单的环境配置

  • 前提已经安装了typescript,如果未安装则执行下面命令进行全局安装

    npm install -g typescript
    
  • 创建&初始化项目

    #创建项目文件夹
    mkdir NodeDemo
    #进入跟目录
    cd NodeDemo
    #初始化项目
    npm init
    

    至此会生成一个包含package.json文件的项目

  • 生成TypeScript配置文件

    #进入项目跟目录,执行脚本自动生成tsconfig.json配置文件
    tsc --init
    

    按照需要配置tsconfig.json文件即可,比如需要支持ES6

    {
      "compilerOptions": {
        ...
        "target": "ES2015",     /*指定ECMAScript(js)版本*/
        ...
      }
    }  
    
  • 使用ES6书写第一个typescript

    class Person {
        //声明ES6中的Set对象
        set: Set<any>;
        //构造函数中初始化set
        constructor() {
            this.set = new Set();
            this.set.add({name: 'Tom', age: 20, address: 'shanghai'});
            this.set.add({name: 'Judy', age: 26, address: 'beijing'});
            this.set.add({name: 'Susan', age: 30, address: 'guangzhou'});
        }
        //获取人员集合方法
        getPersonList(): Set<any> {
            return this.set;
        }
    }
    //测试
    let person = new Person();
    console.log(person.getPersonList());
    

    使用tsc对ts文件进行编译生成对应js文件

    tsc index.ts
    

    使用node命令测试

    node index.js
    #输出
    #	Set {
    #  	{ name: 'Tom', age: 20, address: 'shanghai' },
    #  	{ name: 'Judy', age: 26, address: 'beijing' },
    #  	{ name: 'Susan', age: 30, address: 'guangzhou' }
    #	}
    

2. ES6 Array.of 与 Array.from区别

  • Array.from()

    用来将一个伪数组或者可迭代的对象创建一个新的、浅拷贝的数组实例

    • 伪数组对象(拥有一个 length 属性和若干索引属性的任意对象)
    • 可迭代对象(可以获取对象中的元素,如 Map和 Set 等)

    Array、Map、Set、String、TypedArray、函数的 arguments 对象、NodeList 对像都可进行转换

    1. Map
    2. Set
    3. String
    4. TypedArray
    5. 函数的 arguments 对象
    6. NodeList 对象

    格式

    Array.from(likeArray,mapFn,thisArg)

    • arrayLike:类似数组或可迭代对象。
    • mapFn(可选):如果指定了该参数,数组中每个元素都会执行该函数返回新值。
    • thisArg(可选):执行回调函数mapFn时,指定的this对象。
    • 返回值:一个新数组实例。

    实例

    let str = 'hello';
    let strArr = Array.from(str);    //将字符串转换成一个数组
    //['h','e','l','l','o']
    

    指定mapFn函数

    let str = '1234';
    //将数字123通过Array.from转换成数组,并对里面每个元素进行乘2,返回新数组实例
    let strArray = Array.form(str,function(value){
        return Number.parseInt(value) *2;
    });
    //numArray = [2,4,6,8]
    

    指定thisArg

    let str = '1234';
    //定义mapFn函数
    let mapFn = {
      calculate:function(value){
        return Number.parseInt(value) *2;
      }
    }
    //将num转换为数组
    let numArray = Array.from(str,function(value)=>{
             //这里this是指向mapFn对象,因此可调用其calculate方法,对每个元素进行计算,返回新元素
             return this.calculate(value);                 
    },mapFn);//指定mapFn函数中this指向对象
    
  • Array.of()

    方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。

    Array.of()Array 构造函数之间的区别在于处理整数参数:

    • Array.of(7) 创建一个具有单个元素 7 的数组,

    • Array(7) 创建一个长度为7的空数组(**注意:**这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)。

    格式

    Array.of(element0[, element1[, ...[, elementN]]])

    实例

    //初始化一个整型数组
    let numArray = Array.of(1,2,3,4,5);
    //numArray = [1,2,3,4,5]
    
    //初始化一个字符串数组
    let strArray = Array.of('Tom','Judy','Susan');
    //strArray = ['Tom','Judy','Susan']
    

3. instanceof 与typeof 区别

  • typeof

    typeof 是一个运算符,用来判断变量是什么类型,返回一个字符串用来表示判断的变量的数据类型。一般只能返回如下几个结果

    • number
    • string
    • boolean
    • object
    • function
    • undefined
    console.log(typeof 123);    //number
    console.log(typeof 'Tom');  //string
    console.log(typeof (()=>{}) //function
    console.log(typeof {});     //object
    
  • instanceof

    instanceof 一般用于判断某个对象是否属于另一个对象的实例,返回布尔类型

    class A{}
    class B{}
    
    let c = new A();
    console.log(c instanceof A);  //true
    console.log(c instanceof B);  //false
    

    闲暇之余写了个小程序,欢迎大家扫码使用
    在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值