title: TypeScript学习笔记
date: 2020-06-21 13:34:45
tags:

  • TypeScript
  • 笔记
    categories: 学习
    copyright: false
    top_img: /img/bg3.png

  1. npm install typescript -g

创建配置文件

  1. tsc --init

监视ts文件

  1. tsc -w

基础类型

布尔类型:boolean

数字类型:number

字符串类型:string

数组类型:array

对象类型:Object

  1. let arr=number[] = [1,2,3]//第一种
  2. let arr=Array<number> = [1,2,3]//第二种

元组类型:tuple

  1. let arr:[number,string] = [1,'str']//每一个位置一个类型

枚举类型:enum

  1. enum Err {null=-1,undefined=-2,success=1}
  2. let e:Err = Err.null
  3. console.log(e)//-1 如果赋值了就是赋值的数值,如果未赋值,显示的就是下标
  1. enum Err {null,undefined,success}
  2. let e:Err = Err.null
  3. console.log(e)//0

任意类型:any

nullundefined (nerve类型的子类型)

viod类型:表示方法没有返回任何类型

  1. function a():void{
  2. console.log('aaa')
  3. }

never类型:代表从不会出现的值,这意味着声明never类型的变量只能被never类型所赋值

函数定义

  1. function logInfo(name:string,age:number,sex:string):string{
  2. return `我叫${name},是个${sex}人,今年${age}岁`
  3. }

函数参数可选:

TS函数定义,调用函数时,参数是必传的,如果需要制定参数可不传,则需要指定参数可选.

  1. function logInfo(name:string,age?:number,sex?:string):string{
  2. return `我叫${name},是个${sex}人,今年${age}岁`
  3. }

在参数后加问号.且可选参数必须配置到参数的最后面

默认参数

  1. function logInfo(name:string,age:number=18,sex?:string):string{
  2. return `我叫${name},是个${sex}人,今年${age}岁`
  3. }

剩余参数

  1. function add(...result:number[]):number{
  2. return result.reduce((a,b)=>a+b)
  3. }

函数重载

  1. function getInfo(name: string): string
  2. function getInfo(age: number): number
  3. function getInfo(str: any): any {
  4. if (typeof str === 'string') {
  5. return `我叫${str}`
  6. } else {
  7. return `我今年${str}岁`
  8. }
  9. }

限制传入参数的类型,但是允许几个类型.

  1. class Person{
  2. name:string//和es6不同,es6不需要写这么一行
  3. constructor(name:string){
  4. this.name=name
  5. }
  6. run():void{
  7. console.log(this.name)
  8. }
  9. }
  10. let p = new Person('张三')
  11. p.run()//张三

继承

  1. class Person{
  2. name:string//和es6不同,es6不需要写这么一行
  3. constructor(name:string){
  4. this.name=name
  5. }
  6. run():void{
  7. console.log(this.name)
  8. }
  9. }
  10. class Man{
  11. constructor(name:string){
  12. super(name)
  13. }
  14. }
  15. let zs = new Man('张三')

类里面的修饰符

public:公有,在类里面,子类,类外面都可以访问

protected:保护类型,在类里面,子类里面可以访问,再累外部无法访问.

private:私有,在类里面可以访问,在子类里和外部都无法访问

属性如果不加修饰符,默认就是公有

类里面的静态方法和静态属性

  1. class Person{
  2. public name:string
  3. constructor(name:string){
  4. this.name=name
  5. }
  6. run():void{
  7. console.log(this.name)
  8. }
  9. static print():void{
  10. console.log('静态方法')
  11. }
  12. }

静态方法没发调用类里的属性,只能使用静态属性

多态

父类定义一个方法不去实现,让继承他的子类去实现.每一个子类有不同的表现形式.

  1. class Human{
  2. public sex:string
  3. constructor(sex:string){
  4. this.sex=sex
  5. }
  6. like():void{
  7. console.log('人类的性取向')
  8. }
  9. }
  10. class Man extends Human{
  11. constructor(sex:string){
  12. super(sex)
  13. }
  14. like():void{
  15. console.log('我喜欢女人')
  16. }
  17. }
  18. class WoMen extends Human{
  19. constructor(sex:string){
  20. super(sex)
  21. }
  22. like():void{
  23. console.log('我喜欢男人')
  24. }
  25. }

抽象类

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

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

abstract抽象方法只能放在抽象类里面

抽象类和抽象方法是用来定义标准的

  1. abstract class Human{
  2. public sex:string
  3. constructor(sex:string){
  4. this.sex=sex
  5. }
  6. abstract like():void{
  7. console.log('人类的性取向')
  8. }
  9. }
  10. class Man extends Human{
  11. constructor(sex:string){
  12. super(sex)
  13. }
  14. like():void{
  15. console.log('我喜欢女人')
  16. }
  17. }
  18. class WoMen extends Human{
  19. constructor(sex:string){
  20. super(sex)
  21. }
  22. like():void{
  23. console.log('我喜欢男人')
  24. }
  25. }

接口

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

接口定义了某一批类所需要遵循的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供哪些方法,提供这些方法的类就可以满足实际需要,typescript中的接口类似于java,同时还增加了更灵活的接口类型,包括属性/函数/可索引和类等.

属性类接口

  1. function printName(name:FullName) {
  2. return name.firstName+name.lastName
  3. }
  4. printName({
  5. firstName:'张',
  6. lastName:'三',
  7. age:18//报错 如果直接在实参中写了接口不包含的属性,就会报错
  8. })
  1. interface FullName{
  2. firstName:string;
  3. lastName:string;
  4. }
  5. function printName(name:FullName) {
  6. return name.firstName+name.lastName
  7. }
  8. let obj = {
  9. firstName:'张',
  10. lastName:'三',
  11. age:18
  12. }
  13. printName(obj)//在外部定义的对象,只要对象中包含接口指定的即可.

函数类型接口

  1. interface encrypt{
  2. (key:string,value:string):string
  3. }
  4. const md5:encrypt = (key:string,value:string):string => key+value
  5. const getInfo:encrypt = (key:string,value:string):string => key+value

可索引接口

主要是对数组,对象进行约束

  1. interface userArr{
  2. [index:number]:string
  3. }
  4. let manArr:userArr = ['11','123']
  1. interface userObject{
  2. [index:string]:string
  3. }
  4. let manArr:userObject = {name:'张三',sex:'男'}

类类型接口

  1. interface Human{
  2. name:string
  3. eat(str:string):void
  4. }
  5. class Man implements Human{
  6. name:string
  7. constructor(name:string){
  8. this.name = name
  9. }
  10. eat(str:string):void{
  11. console.log(str)
  12. }
  13. }

接口扩展

  1. interface Animal {
  2. eat():void
  3. }
  4. interface Human extends Animal{
  5. name: string
  6. work(): void
  7. }
  8. class Man implements Human {
  9. name: string
  10. constructor(name: string) {
  11. this.name = name
  12. }
  13. work(): void {
  14. console.log(this.name)
  15. }
  16. eat():void{
  17. console.log('吃饭');
  18. }
  19. }

泛型

泛型函数

泛型就是解决类 接口 方法的复用性,以及对不特定数据类型的支持

  1. function printInfo<T>(value:T):T{
  2. return value
  3. }
  4. printInfo<number>(123)//正确的
  5. printInfo<number>('111')//错误的

T表示泛型:具体什么类型是调用这个方法的时候决定的

泛型类

  1. class MinClass<T>{
  2. public list:T[] = []
  3. constructor(list:T[]){
  4. this.list = list
  5. }
  6. add(value:T):void{
  7. this.list.push(value)
  8. }
  9. min():T{
  10. let minNumber = this.list[0]
  11. for(let i=0;i<this.list.length;i++){
  12. if(minNumber>this.list[i]){
  13. minNumber = this.list[i]
  14. }
  15. }
  16. return minNumber
  17. }
  18. }

泛型接口

  1. //方法一
  2. interface configFn {
  3. <T>(str: T): T
  4. }
  5. const printInfo: configFn = <T>(str: T) => str
  6. printInfo<number>(123)//正确的
  7. printInfo<number>('111')//错误的
  1. //方法二
  2. interface configFn<T> {
  3. (str: T): T
  4. }
  5. const printInfo = <T>(str: T) => str
  6. const printInfo1:configFn<number> = printInfo
  7. printInfo<number>(123)//正确的
  8. printInfo<number>('111')//错误的

把类作为参数来约束数据传入的类型的泛型类

  1. class User{
  2. userName:string | undefined
  3. passWord:string | undefined
  4. }
  5. class mysqlDB{
  6. add(user:User):boolean{
  7. console.log(user)
  8. return true
  9. }
  10. }
  11. let u = new User()
  12. u.userName = '张三'
  13. u.passWord = '123456'
  14. let DB = new mysqlDB()
  15. DB.add(u)

上面的数据库类 ,只能接收user,局限性大.可以用泛型来制定多种类校验

  1. class User{
  2. userName:string | undefined
  3. passWord:string | undefined
  4. }
  5. class mysqlDB<T>{
  6. add(info:T):boolean{
  7. console.log(info)
  8. return true
  9. }
  10. }
  11. let u = new User()
  12. u.userName = '张三'
  13. u.passWord = '123456'
  14. let DB = new mysqlDB<User>()
  15. DB.add(u)

命名空间

  1. namespace A{
  2. export class User{
  3. userName:string | undefined
  4. passWord:string | undefined
  5. }
  6. export class mysqlDB<T>{
  7. add(info:T):boolean{
  8. console.log(info)
  9. return true
  10. }
  11. }
  12. }
  13. let u = new A.User()
  14. u.userName = '张三'
  15. u.passWord = '123456'
  16. let DB = new A.mysqlDB<A.User>()
  17. DB.add(u)

装饰器

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

类装饰器

装饰器修改

  1. function logClass(info:any):void{
  2. console.log(info)
  3. info.prototype.apiUrl = 'www.flfper.com'
  4. }
  5. @logClass
  6. class HttpClient{
  7. constructor(){
  8. }
  9. getData(){
  10. }
  11. }
  12. let http:any = new HttpClient()
  13. console.log(http.apiUrl)

装饰器重写类

  1. function logClass(info:any){
  2. console.log(info)
  3. return class extends info{
  4. apiUrl:any= '-----111111'
  5. getData(){
  6. console.log(this.apiUrl)
  7. }
  8. }
  9. }
  10. @logClass
  11. class HttpClient{
  12. public apiUrl:string |undefined
  13. constructor(apiUrl:string){
  14. this.apiUrl = apiUrl
  15. }
  16. getData(){
  17. console.log(this.apiUrl)
  18. }
  19. }

属性装饰器

  1. function logPropety(str:string){
  2. return function(target:any,attr:string){
  3. console.log(target,attr)
  4. target[attr] = '装饰器修改属性'
  5. }
  6. }
  7. @logClass('给装饰器传参')
  8. class HttpClient{
  9. @logPropety('修改的属性')
  10. public url:string| undefined
  11. getData(){
  12. }
  13. }
  14. let http:any = new HttpClient()
  15. console.log(http.apiUrl)

方法装饰器

  1. function get(str: string) {
  2. return function (target: any, methodName: string, desc: any) {
  3. console.log(target);
  4. console.log(methodName);
  5. console.log(desc.value);
  6. const oldMethod = desc.value
  7. desc.value = function (...reset: any[]) {
  8. console.log(reset, '我是新方法');
  9. oldMethod.apply(this, reset)
  10. }
  11. }
  12. }
  13. class HttpClient {
  14. public url: string | undefined
  15. @get('装饰器传参')
  16. getData(...reset: any[]) {
  17. console.log(reset,'我是老方法');
  18. }
  19. }
  20. let http: any = new HttpClient()
  21. http.getData(1,2,3)

参数装饰器

  1. function logParams(str: string) {
  2. return function (target: any, methodName: string, paramsIndex: any) {
  3. console.log(target);
  4. console.log(methodName);
  5. console.log(paramsIndex);
  6. }
  7. }
  8. class HttpClient {
  9. public url: string | undefined
  10. getData(@logParams('111') id:any) {
  11. console.log('老方法',id);
  12. }
  13. }
  14. let http = new HttpClient()
  15. http.getData(1)

装饰器的写法

普通装饰器(无法传承)

  1. function logClass(info:any):void{
  2. console.log(info)
  3. info.prototype.apiUrl = 'www.flfper.com'
  4. }
  5. @logClass
  6. class HttpClient{
  7. constructor(){
  8. }
  9. getData(){
  10. }
  11. }
  12. let http:any = new HttpClient()
  13. console.log(http.apiUrl)

装饰器工厂

  1. function logClass(info:string){
  2. return function(target:any){
  3. console.log(info)
  4. console.log(target)
  5. target.prototype.apiUrl = info
  6. }
  7. }
  8. @logClass('给装饰器传参')
  9. class HttpClient{
  10. constructor(){
  11. }
  12. getData(){
  13. }
  14. }
  15. let http:any = new HttpClient()
  16. console.log(http.apiUrl)

装饰器是过去几年中JS最大的成就之一,已经是ES7的标准特性之一

装饰器的执行顺序

属性>方法>方法参数>类

如果有多个同样的装饰器它会限制性后面的