文章目录
简介
-
微软开发
的自由和开源的编程语言
。 -
是
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 Studio,Sublime Text2,WebStorm,PHPStorm,Eclipse等
基础语法
TypeScript 程序由以下几个部分组成
- 模块
- 函数
- 变量
- 语句和表达式
- 注释
第一个typeScript程序
-
编写我们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); }
-
进入我们编写的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); }
-
执行js脚本运行
node index.js Tom Judy 20
-
TypeScript转换为JavaScript过程如下图
我们可以同时编译多个ts文件
tsc file1.ts file2.ts file3.ts
TypeScript 关键字
break | as | catch | switch |
---|---|---|---|
case | if | throw | else |
var | number | string | get |
module | type | instanceof | typeof |
public | private | enum | export |
finally | for | while | void |
null | super | this | new |
in | return | true | false |
any | extends | static | let |
package | implements | interface | function |
new | try | yield | const |
continue | do |
TS语法注意
- 会忽略空白、换行、制表符
- 区分大小写
- 分号可选(建议使用)但是同一行多条语一定要用分号来分隔
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数据类型包含如下:
any
、number
、string
、boolean
、数组
、元组
、枚举
、void
、null
、undefined
、never
any
任意类型,可赋予任意类型的值,任意类型会在编译时跳过检查!
number
数值类型,双精度64位浮点值,可表示整数和分数
Number
是原始数值(number)的包装对象,该对象支持属性如下:
-
属性
- MAX_VALUE:可表示最大的数。
- MIN_VALUE:可表示最小的数,最接近0的正数。
- NaN:非数字值。
- NEGATIVE_INFINITY:负无穷大,溢出时返回该值,该值小于MIN_VALUE。
- POSITIVE_INFINITY:正无穷大,溢出时返回该值,该值大于MAX_VALUE。
- prototype:Number对象的静态属性,使您有能力向该对象添加属性和方法。
- 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
-
方法
- toExponential(int):将数值转换为指数计数法(指定保留小数位长度)
- toFixed(int):把数值转换为字符串(指定小数位数)
- toPrecision(int):把数值格式化为指定长度字符串(指定字符串长度)。
- 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]; //错误,元组元素类型与定义对应类型不同
枚举
枚举用于定义**数值
**集合
注意:
默认情况下,枚举是基于 0 的,也就是说第一个值是 0,后面的值依次递增
- 可以向枚举传递一个值,然后获取对应的名称值
- 枚举值除了设置数值,还可以设置字符串,但是不推荐设置字符串
枚举不设置值,枚举值默认是从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...of
、forEach
、every
和some
循环
在 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]; //遍历剩余参数数组 for(let 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
**关键字导入。
模块导入导出格式
-
定义接口并导出(IPerson.ts)
//定义IPerson接口并导出 export interface IPerson{ name:string; age:number; getInfo():string; }
-
定义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; } }
-
在其他文件中使用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 对像都可进行转换
- Map
- Set
- String
- TypedArray
- 函数的 arguments 对象
- 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
闲暇之余写了个小程序,欢迎大家扫码使用