Typescript的装饰器使用起来太优雅了,想加什么功能直接装饰上就好了。
效果
实现了两种版本的修改console.log默认的打印样式方法。
效果就是可以打印五颜六色的字体。
throw Error 版
const fancy_console: MethodDecorator =
(_a, _b, descriptor: PropertyDescriptor) => {
// 取出被装饰的方法
const method = descriptor.value
// “装饰”该方法
descriptor.value = function () {
try {
method.apply(this, arguments)
} catch (e: any) {
const r = (Math.random() * 255) | 0
const g = (Math.random() * 255) | 0
const b = (Math.random() * 255) | 0
console.log(`%c${e.message}`, `color:rgb(${r},${g},${b});font-size:16px`);
}
}
}
测试代码:
class Test {
value = 1;
@fancy_console
method() {
console.log(this); // Test { value: 1 }
throw new Error("haha") // haha
throw new Error("haha") //
}
}
(new Test).method()
throw new Error() 这种方式虽然结构上很完美,但是只能打印一次,第二次throw的时候代码已经执行完了。
所以干脆在类上添加一个 log 方法,打印的时候调自己写的 log 方法。
自定义 log 方法版
const fancy_console: ClassDecorator =
(target: Function) => {
// 在被装饰的原型对象上添加 log 方法
target.prototype.log = function (content: string) {
const r = (Math.random() * 255) | 0
const g = (Math.random() * 255) | 0
const b = (Math.random() * 255) | 0
console.log(`%c${content}`, `color:rgb(${r},${g},${b});font-size:16px`);
}
}
// 防止报log不存在的Error
interface Test {
log: Function
}
@fancy_console
class Test {
value = 1;
method() {
console.log(this);
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
this.log("我就是我")
}
}
(new Test).method()
效果如文章开头截图。
这种方式我比较满意了。
Node.js 专用版
最近写Nodejs 发现打印对象和函数的时候不会具体地打印其内容,而是这样:
console.log({ name: 1, child: [{ obj: { key: 1 } }] })
// { name: 1, child: [ { obj: [Object] } ] }
console.log(function () { console.log(123) })
// [Function (anonymous)]
console.log([1, 23, 231123, 314, [34, 23]])
// [ 1, 23, 231123, 314, [ 34, 23 ] ]
非常影响阅读!
装饰器实现:
import { js_beautify } from "js-beautify";
const fancy_console: ClassDecorator =
(target: Function) => {
target.prototype.log = function (content: string | Function | object) {
let message = content;
if (typeof message === "object") {
// 对象类型——使用JSON格式化
message = JSON.stringify(message, null, 2)
} else if (typeof message === "function") {
// 函数代码——调用模块fromat
message = js_beautify(message.toString(),
{ indent_size: 2, space_in_empty_paren: true })
}
// 打印处理结果
console.log(message);
}
}
interface Test {
log: (content: string | Function | object) => void
}
同样的在类上使用装饰器,效果:
// 对象
{
"name": 1,
"child": [
{
"obj": {
"key": 1
}
}
]
}
// 函数代码
function() {
console.log(123);
}
// 二维数组
[
1,
23,
231123,
314,
[
34,
23
]
]
瞬间清晰了许多!