TypeScript
什么是TypeScript
TypeScript就是所谓JavaScript的超集,TypeScript允许程序员在其代码中使用面向对象的构造,然后将其转化为JavaScript
TypeScript的好处
- 静态类型,typescript代码比JavaScript代码更易于预测和更易于调试
- 面向对象的功能(模块和命名空间)使组织大型代码库更易于管理
- 编译步骤在达到运行时之前捕获错误
- 流行框架angular是用typescript编写的
- typescript类似于coffeescript,另一种编译为javascript的语言,不过由于静态类型,前者比后者更加灵活
1. 安装和设置
npm install typescript -g
tsc helloword.ts
2. 编译为javascript(vscode)
-
tsc --init
生成一个tsconfig.json
文件 - 修改文件
"outDir": "./js"
- 点击
任务
- 运行任务,选择
监视tsconfig
3. TS中的数据类型(11)
- 布尔(boolean)
- 字符串(string)
- 数值(number)
- undefined
var num:number|undeined
- null
- 数组(Array): 两种定义方法
var arr:number[] = [1, 2, 3] var arr:Array<number> = [1, 2, 3]
- 任意(any)
- 枚举(enum): 用一定的单词代表某些信息
enum Flag { success= 1, error= 2 } var flag:Flag = Flag.success console.log(flag) //1
enum Flag { success, error } var flag:Flag = Flag.success console.log(flag) //0 当没有给类型中的变量名赋值时,它的值为下标,如果改变了其中的数值,之后的数值会累加下去
- void: 定义方法时该方法没有返回值
function getInfo():void{ ... }
- 元组类型(tuple):属于数组的一种
var arr:[number, string] = [1, 'a'] //正确 var arr:[number, string] = ['a', 2] //错误
- never: 1.从不会出现的值 2. undefined和null属于never中的一种
4. TypeScript中的函数
- 定义
function getInfo():number{ return 123 } var getInfo = function():number{ return 123 }
- 方法可选参数(表示参数可传可不传)
可选参数一定要配置到参数的最后面
function getInfo(num:number, num1?:number):number{ if(num1){ return num + num1 }else{ return num } } alert(getInfo(1))
- 默认参数
function getInfo(num:number=11):number{ return num }
- 剩余参数
function getInfo(...rest:number[]):number{ var num:number = 0 for(var i:number = 0 ; i < rest.length ; i++){ num += rest[i] } return num } getInfo(1, 2, 3, 4) //10 getInfo() //0
- 函数重载(通过传入不同的参数实现不同的功能)
function getInfo(name:string):string function getInfo(name:string, age:number):string function getInfo(name:any, age?:any):string{ if(age){ return `我的名字是${name},我的年龄是${age}` } return `我的名字是${name}` }
- 箭头函数
3. 静态打字
4. 数组
5. 接口
- 属性类接口
interface FullName{ firstName:string; secondName?:string; //可选属性 } function getInfo(info:FullName):void{ console.log(info.firstName + '--' + info.secondName) } getInfo({ firstName: 'ou', secondName: 'chi' })
- 函数类型接口
interface entry { (key:string, value:string):string } var md5:entry = function(key:string,value:string):string{ return `key:${key}--value:${value}` }
- 可索引接口(对象,数组的约束)(不常用)
interface UserArr { [index:number]: string }
- 类类型接口(和抽象类有点相似)
class Dog implements(实现) Animal
interface Animal { name: string; eat():void; } class Dog implements Animal { public name:string; constructor(name:string){ this.name = name } eat():void{ console.log(this.name) } } var d1 = new Dog('dogdog') d1.eat()
- 接口拓展(接口可继承)
interface Animal { name: string } interface Person { age: number } class Web implements Person { name: string age: number constructor(name:string, age:number){ this.name = name this.age = age } getInfo():void{ console.log(this.name + '--' + this.age) } }
6. 类
- 定义类
class Person { name:string; constructor(name:string){ this.name = name } run():void{ console.log(this.name + '在运动') } } var p = new Person('张三') p.run()
- ts中实现继承
class Person { name:string; constructor(name:string){ this.name = name } work():void{ console.log(this.name + '在工作') } } class Web extends Person { constructor(name:string){ super(name) } } var w1 = new Web('程序员') w1.work()
- 继承的探讨,子类方法与父类一致
子类方法会覆盖父类的方法
- 类中的修饰符
- public(公有的)
在类内部、子类、类外部都可以访问到该属性或方法
class Person { public name:string; constructor(name:string){ this.name = name } } var p1 = new Person('王五') console.log(p1.name)
- protected(受保护的)
在内部、子类中可以访问到该属性或方法,在类外部不能访问到该属性或方法
class Person { protected name:string; constructor(name:string){ this.name = name } } class Web extends Person { constructor(name:string){ super(name) } eat():void{ console.log(this.name + 'eating') //子类中可以访问到该属性 } } var p1 = new Person('王五') var web1 = new Web('小六') web1.eat() // console.log(p1.name) //会报错,因为类外部不能访问protected属性 // console.log(web1.name) //会报错,因为类外部不能访问protected属性
- private(私有的)
只能在类内部访问到该属性或方法
class Person { protected name:string; constructor(name:string){ this.name = name } } class Web extends Person { constructor(name:string){ super(name) } eat():void{ console.log(this.name + 'eating') //报错 } } var p1 = new Person('王五') var web1 = new Web('小六') web1.eat() // console.log(p1.name) //会报错,因为类外部不能访问private属性 // console.log(web1.name) //会报错,因为类外部不能访问private属性
- public(公有的)
- 静态属性、静态方法(static)
- 加个static关键词就是静态方法或者静态属性
- 静态方法不能直接调用实例属性和方法
- 静态方法只能调用静态属性和方法??
- 多态
在父类中定义方法但是不去实现,让它的子类去实现,每个子类有不同的表现 - 抽象类(abstract)
抽象类不能直接被实例化,它其实类似一个标准,提供一个基类,规定抽象类中的子类必须实现基类中的抽象方法 abstract class Person { abstract run():void } class Web extends Person { run(){ console.log('run') } } var w1 = new Web() w1.run()
7. 泛型
解决类,接口,方法的可复用性,以及对不特定的数据类型的支持
- 函数泛型
function getInfo<T>(value:T):T{ console.log(value) } getInfo<number>(15) getInfo<string>('abc')
- 类泛型
class MinClass<T>{ public list:T[] = [] add(value:T):void{ this.list.push(value) } sort():any{ var min:T = this.list[0] for(var i:number = 0 ; i < this.list.length ; i++){ if(this.list[i] < min){ min = this.list[i] } } return min } } var m1 = new MinClass<number>() m1.add(1) m1.add(2) m1.add(-1) m1.add(-5) m1.add(10) alert(m1.sort())
- 接口泛型
interface Config { <T>(key:T,value:T):T } var getInfo:Config = function<T>(key:T,value:T):T{ console.log(`${key}--${value}`) } getInfo<number>(1,2)
- 把类当做参数的泛型类
例子:定义一个操作数据库的库 要求:有add、get、update、delete方法 interface Dbi<T> { add(info:T):boolean get(id:number):boolean delete(id:number):boolean update(info:T,id:number):boolean } class User<T> implements Dbi<T>{ add(info: T): boolean { console.log(info) return true } get(id: number): boolean { throw new Error("Method not implemented.") } delete(id: number): boolean { throw new Error("Method not implemented.") } update(info: T, id: number): boolean { throw new Error("Method not implemented.") } } class U { username:string|undefined password:string|undefined } var u = new U() u.username = '123' u.password = '789' var user = new User<U>() user.add(u)
8. 模块和命名空间
import和export(浏览器中不能直接执行,要通过nodejs)
9. 装饰器
- 类装饰器
传入一个参数 对静态成员来说是构造函数,对实例成员来说是类的原型对象 function logClass(params:any){ return function(target:any){ console.log(target) console.log(params) } } @logClass('aaa') class Per { }
- 属性装饰器
传入两个参数 1. 对静态成员来说是类的构造函数,对实例成员来说是类的原型对象 2. 属性的名称 function logAttr(params:any){ return function(target:any, attrName:string){ console.log(target.constructor) console.log(attrName) } } @logClass('aaa') class Per { @logAttr('as') public username:string|undefined }
- 方法装饰器
传入三个参数 1. 对静态成员来说是类的构造函数,对实例成员来说是类的原型对象 2. 方法的名称 3. 方法的属性描述符 function logFn(params:any){ return function(target:any, name:string, des:any){ console.log(target) console.log(name) console.log(des) } } @logClass('aaa') class Per { @logAttr('as') public username:string|undefined @logFn('bbc') add():void{} }
- 方法参数装饰器
传入三个参数 1. 对静态成员来说是类的构造函数,对实例成员来说是类的原型对象 2. 方法的名称 3. 参数在函数列表中的索引