同名接口声明合并
interface InfoInter {
name: string
getRes(input: string): number
}
interface InfoInter {
age: number
getRes(input: number): string
}
// 相当于
interface InfoInter {
name:string
age:number
getRes(input:string):number
// +1 overload
getRes(input: number): string
}
枚举,命名空间合并
enum Colors {
red,
green,
pink
}
namespace Colors {
export const yellow = 3
}
console.log(Colors)
//{0: "red", 1: "green", 2: "pink", red: 0, green: 1, pink: 2, yellow: 3}
装饰器
- 提案阶段,慎用
- 有4类装饰器:类装饰器,属性装饰器,参数装饰器,访问修饰器
类装饰器
类装饰器在类声明之前被声明,应用于类构造函数,可以监视、修改、替换类的定义,传入一个参数
function logClz(params:any) {
console.log(params) // class HttpClient
}
@logClz
class HttpClient {
constructor() {
}
}
// logClz() 接收的参数params就是被装饰的类HttpClient
- 为
HttpClient
动态扩展属性属性和方法
function logClz(params:any) {
params.prototype.url = 'xxxx';
params.prototype.run = function() {
console.log('run...');
};
}
var http:any = new HttpClient();
http.run(); // run...
装饰器工厂:闭包形式
let sign = null
function setName(name: string) {
return (target: new () => any) => {
sign = target
console.log(target.name)
}
}
@setName('liu')
class ClassDec {}
console.log(sign === ClassDec) // true
在使用装饰器工厂时,如果不想给装饰器传参,可以把参数声明为可选参数,但使用装饰器时仍然不能丢失小括号!
@setName()
属性装饰器
- 属性装饰器表达式会在运行时当作函数被调用,传入两个参数
- 成员的名字;
function logProp(params:any) {
return function(target:any, attr:any) {
console.log(target) // { constructor:f, getData:f }
console.log(attr) // url
target[attr] = params; //通过原型对象修改属性值 = 装饰器传入的参数
target.api = 'xxxxx'; //扩展属性
target.run = function() { //扩展方法
console.log('run...');
}
}
}
class HttpClient {
@logProp('http://baidu.com')
public url:any|undefined;
constructor() { }
getData() {
console.log(this.url);
}
}
var http:any = new HttpClient();
http.getData(); // http://baidu.com
console.log(http.api); // xxxxx
http.run(); // run...
方法修饰器
- 运行时被当做函数调用,有3个参数。
- 第一个参数:装饰静态成员时,代表类构造函数;装饰实例时,代表类的原型对象
- 第二个参数: 成员名
- 第三个参数 成员属性描述符 : configurable 可配置 writeable 可写 enumerable 可枚举
- 使用Object.defineProperty改写属性描述符
interface Objex {
[key: string]: any
}
let obj12: Objex = {
age: '123'
}
Object.defineProperty(obj12, 'name', {
value: 'chen',
configurable: true,
writable: true,
enumerable: true
})
obj12.name = 'XXXXXXXXXXXX'
console.log(obj12.name)
for (const key in obj12) {
console.log(key)
}
方法参数修饰器
参数定义同上 方法修饰器
function required(target: any, properName: string, index: number) {
console.log(`修饰${properName}的${index + 1}`)
}
class ClassI {
public name: string = 'lzw'
public age: number = 24
public getInfo(prefix: string, @required infoType: string): any {
return prefix + ' ' + this[infoType]
}
}
interface ClassI {
[key: string]: string | number | Function
}
装饰器的执行顺序
在TypeScript里,当多个装饰器应用在一个声明上时会进行如下步骤的操作:
- 由上至下依次对装饰器表达式求值;
- 求值的结果会被当作函数,由下至上依次调用.
- 不同装饰器的执行顺序:属性装饰器 > 方法装饰器 > 参数装饰器 > 类装饰器
Comments | NOTHING