TypeScript @decorator in depth
TypeScript @decorator in depth
@decorator
function log(...args: any): void {
console.log('decorator', args)
}
@log('abc')
class Test {
constructor() {
console.log('app');
}
}
const test = new Test();
Reflect
&Object.defineProperty
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
// ✅
console.log('decorators =', decorators);
console.log('target =', target);
console.log('key =', key);
console.log('desc =', desc);
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
// ✅
console.log('(k, v =', k, v);
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
function log(...args) {
console.log('decorator', args);
}
let Test = class Test {
constructor() {
console.log('app');
}
};
Test = __decorate([
log('abc'),
__metadata("design:paramtypes", [])
], Test);
const test = new Test();
@decorator()
DecoratorFactory
// js function 科里化 / js 高阶函数
function DecoratorFactory(...params: any) {
console.log('\nparams =', params, 0);
// new 表示包含构造函数 (ES6 class / ES5 constructor function)
return function <T extends new (...args: any[]) => any>(passedClass: T) {
return class extends passedClass {
name: string;
constructor(...args: any[]) {
super();
this.name = args[0] + '👻';
console.log('this.name =', this.name, 2);
console.log('...args', args, 3);
}
}
}
}
const App = DecoratorFactory('xgqfrms')(
// 传入 class 作为参数
class {
name: string;
constructor(name: string) {
this.name = name;
console.log('app name =', name, 1);
}
}
);
const app = new App('xgqfrms');
console.log('app =', app);
class decorator
fields decorator
// Decorator function return type is 'PropertyDescriptor' but is expected to be 'void' or 'any'.ts(1271)
function fieldDecorator(target: any, prop: string): any {
console.log('target: =', target);
console.log('prop =', prop);
// 修改的是原型链上属性
target[prop] = 'prototype prop value 👻';
// 手动返回新的 description, 替换原来的属性描述符
const description: PropertyDescriptor = {
// writable: false,
value: '👻',
// Uncaught TypeError: Cannot assign to read only property 'name' of object '#<App>'
}
return description;
}
class App {
@fieldDecorator
name: string = 'default';
constructor(name: string) {
this.name = name;
}
}
const app = new App('xgqfrms');
// app.name = '2022';
console.log('app =', app);
console.log('app.name =', app.name);
console.log('app.__proto__.name =', (app as any).__proto__.name);
accessor decorator
methods decorator
static methods decorator
refs
©xgqfrms 2012-2020
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/16151588.html
未经授权禁止转载,违者必究!