(四)Typescript中的泛型 T, 命名空间, 装饰器

加入QQ群:864680898,一起学习进步!点击群名可查看本人网站,有最新文章!

(四)Typescript中的泛型 T, 命名空间, 装饰器

一、泛型 T

  • 为什么要用泛型?

可以在函数调用时自由化传入的值和返回的值

let showInfo = <T>(val: T): T => val;
let myName = showInfo<string>('mySkey');
console.log(myName)
  • 泛型类 泛型类看上去与泛型接口差不多

泛型类使用(<>)括起泛型类型,跟在类名后面

class Method<T> {
  add: (x: T, y: T) => T;
}
let method = new Method<number>();
method.add = (x, y) => x+y
console.log(method.add(1,3))
  • 泛型约束

有时我们要限制泛型中类型

interface Lengthwise {
  name: string;
}

let showInfo = <T extends Lengthwise>(arg: T): T =>{
  console.log(arg);  // Now we know it has a .length property, so no more error
  return arg;
}

showInfo({name: 'mySkey'});

二、命名空间

当应用变得越来越大时,我们需要将代码分离到不同的文件中以便于维护;尽管是不同的文件,它们仍是同一个命名空间,并且在使用的时候就如同它们在一个文件中定义的一样。 因为不同文件之间存在依赖关系,所以我们加入了引用标签来告诉编译器文件之间的关联

  • 多文件的命名空间 (不推荐使用)

使用 /// 方式引入,这是3个 / ,不是注释

新建Person.ts文件

namespace Person {
  export interface PersonInterface {
    name: string;
    age: number;
  }
}

在同级目录下的main.ts中使用

/// <reference path="Person.ts" />
let mySkey: Person.PersonInterface = { name: 'mySkey', age: 23 }
  • 别名 (推荐使用)

使用import q = x.y.z给常用的对象起一个短的名字

import myInterface = Person.PersonInterface;
let mySkey: myInterface = { name: 'mySkey', age: 23 }
  • 外部命名空间

流行的程序库D3在全局对象d3里定义它的功能。 因为这个库通过一个

declare namespace D3 {
    export interface Selectors {
        select: {
            (selector: string): Selection;
            (element: EventTarget): Selection;
        };
    }

    export interface Event {
        x: number;
        y: number;
    }

    export interface Base extends Selectors {
        event: Event;
    }
}

declare let d3: D3.Base;

三、Decorators 装饰器

Javascript里的装饰器目前处在建议征集的第一阶段,但在TypeScript里已做为一项实验性特性予以支持

  • tsconfig.json里启用experimentalDecorators编译器选项: “experimentalDecorators”: true
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性或参数上。 装饰器使用@expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入,就相当于中间件

  • 只有类和类里面的属性,方法,方法中的形参能使用装饰器

装饰器工厂就是一个简单的函数,它返回一个表达式,以供装饰器在运行时调用

多个装饰器调用时时遵循:
1、由上至下依次对装饰器表达式求值。
2、求值的结果会被当作函数,由下至上依次调用。

class Father {
  shape: string = 'ugly';
  showAge(){
    console.log('80年代!')
  }
}

function chageAge(age: number){
  return function (target: any){
    target.prototype.showAge = function () {
      console.log('我是00后的,已经不是小朋友了!我今年都'+ age +'岁了')
    }
  }
}

@chageAge(10)
class Son extends Father{

}

let father = new Father();
let son = new Son();
father.showAge()
son.showAge()

上面这种类及其实例并不能感知或者修改存取在类上元数据,但是我们可以通过装饰器和注解在编译时动态的修改它们的行为,即我们写了一个函数去修改函数,我们把这样的行为称作元编程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值