当前位置: 首页 > news >正文

TypeScript 装饰器都有那些应用场景?如何更快的上手?

TypeScript 装饰器简介

在 TypeScript 中,装饰器(Decorators)是一种特殊的语法,用于在类、类方法、属性、访问器等上动态地添加行为或修改现有行为。装饰器可以用来增强类的功能、修改方法的行为,或者修改类的元数据等。它们通常用于元编程和 AOP(面向切面编程)等场景。

装饰器在 TypeScript 中的实现基于 ECMAScript 提案的实验性特性,但目前 TypeScript 已经支持了装饰器的编写和使用。需要注意的是,装饰器特性必须通过 experimentalDecorators 编译选项开启。

开启装饰器支持

tsconfig.json 中配置:

{"compilerOptions": {"experimentalDecorators": true}
}

装饰器的类型

装饰器可以应用于以下几种目标:

  1. 类装饰器 (Class Decorators):应用于类构造函数,修改类的行为或元数据。
  2. 方法装饰器 (Method Decorators):应用于类的方法,允许修改方法的属性或行为。
  3. 属性装饰器 (Property Decorators):应用于类的属性,用于修改或定义属性的元数据。
  4. 访问器装饰器 (Accessor Decorators):应用于类的 getter 或 setter 方法。
  5. 参数装饰器 (Parameter Decorators):应用于方法参数,主要用于修改或注入方法参数的元数据。

装饰器的应用场景

装饰器常用于以下几个场景:

  • 类的功能增强:如注入依赖、日志记录、权限校验等。
  • 方法行为修改:例如,控制方法的执行、缓存机制、性能监控等。
  • 自动化注入:在一些框架中,装饰器用来自动注入依赖,比如 Angular 中的服务注入。
  • 性能分析和日志:自动记录函数的调用时间、参数等。

示例:使用装饰器的实际场景

假设我们有一个项目需要记录方法调用的日志,并且需要验证用户是否有权限执行某些操作。我们可以使用装饰器来实现这些功能。

1. 类装饰器

类装饰器通常用于增强类的行为,比如记录日志、依赖注入等。

function Logger(constructor: Function) {console.log(`Class ${constructor.name} is instantiated.`);
}@Logger
class UserService {constructor() {console.log("UserService instance created.");}
}const userService = new UserService();

解释Logger 装饰器会在类实例化时打印出该类的名称。在 @Logger 之后,当 UserService 被实例化时,控制台输出 Class UserService is instantiated.

2. 方法装饰器

方法装饰器可以修改方法的行为或添加额外的功能。我们可以使用方法装饰器来记录日志,验证权限等。

function Log(target: any, propertyName: string, descriptor: PropertyDescriptor) {const originalMethod = descriptor.value;descriptor.value = function (...args: any[]) {console.log(`Method ${propertyName} is called with args: ${args}`);return originalMethod.apply(this, args);};
}class UserService {@LoggetUser(userId: number) {console.log(`Fetching user with ID: ${userId}`);}
}const userService = new UserService();
userService.getUser(42);

解释@Log 装饰器会修改 getUser 方法,在调用该方法时记录日志,打印出方法名和传入的参数。输出结果为:

Method getUser is called with args: [42]
Fetching user with ID: 42
3. 属性装饰器

属性装饰器可以用来修改类的属性行为或元数据。例如,我们可以用它来设置字段的可访问性或记录日志。

function Observable(target: any, propertyName: string) {let value = target[propertyName];const getter = () => {console.log(`Getting value of ${propertyName}: ${value}`);return value;};const setter = (newVal: any) => {console.log(`Setting value of ${propertyName} to: ${newVal}`);value = newVal;};Object.defineProperty(target, propertyName, {get: getter,set: setter,});
}class User {@Observablename: string;constructor(name: string) {this.name = name;}
}const user = new User("Alice");
user.name = "Bob";  // Console logs: Setting value of name to: Bob
console.log(user.name);  // Console logs: Getting value of name: Bob

解释@Observable 装饰器为 name 属性创建了 getter 和 setter 方法,控制属性的访问并记录相关日志。

4. 权限校验的实际应用

装饰器常用于权限校验等场景,检查用户是否有权限执行某个方法。例如:

function PermissionRequired(permission: string) {return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {const originalMethod = descriptor.value;descriptor.value = function (...args: any[]) {const userPermissions = ["READ", "WRITE"];  // 假设的用户权限if (!userPermissions.includes(permission)) {console.log(`Permission denied. Missing permission: ${permission}`);return;}return originalMethod.apply(this, args);};};
}class DocumentService {@PermissionRequired("WRITE")editDocument() {console.log("Document is being edited.");}
}const documentService = new DocumentService();
documentService.editDocument();  // 如果权限包含 "WRITE",则输出 "Document is being edited."

解释@PermissionRequired 装饰器会在方法执行前检查当前用户的权限。如果权限不足,则拒绝执行方法。

组合使用装饰器

在实际项目中,装饰器可以进行组合使用,进行多种功能的扩展。例如,我们可以结合使用日志记录和权限校验装饰器:

function Log(target: any, propertyName: string, descriptor: PropertyDescriptor) {const originalMethod = descriptor.value;descriptor.value = function (...args: any[]) {console.log(`Calling method ${propertyName} with arguments: ${args}`);return originalMethod.apply(this, args);};
}function PermissionRequired(permission: string) {return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {const originalMethod = descriptor.value;descriptor.value = function (...args: any[]) {const userPermissions = ["READ", "WRITE"];if (!userPermissions.includes(permission)) {console.log(`Permission denied. Missing permission: ${permission}`);return;}return originalMethod.apply(this, args);};};
}class FileService {@Log@PermissionRequired("READ")readFile(filePath: string) {console.log(`Reading file from ${filePath}`);}
}const fileService = new FileService();
fileService.readFile("/path/to/file");

解释:此时,readFile 方法同时拥有日志记录和权限校验的功能,先打印调用日志,再检查权限。

总结

TypeScript 装饰器是一种强大的工具,可以在类、方法、属性、参数等地方进行功能扩展,常用于日志记录、权限校验、性能监控等场景。在实际开发中,装饰器的应用通常能大大减少冗余代码、提高代码的可维护性和灵活性。通过装饰器,开发者可以以声明式的方式对类和方法进行增强,并实现高层次的抽象和代码重用。

常见应用场景:
  • 日志记录
  • 性能监控
  • 权限校验
  • 依赖注入
  • 数据验证
  • 缓存机制

理解装饰器及其应用方式,可以让你在开发中更加得心应手,特别是当代码规模增大时,装饰器能够帮助你以更简洁的方式处理复杂的逻辑。

相关文章:

TypeScript 装饰器都有那些应用场景?如何更快的上手?

TypeScript 装饰器简介 在 TypeScript 中,装饰器(Decorators)是一种特殊的语法,用于在类、类方法、属性、访问器等上动态地添加行为或修改现有行为。装饰器可以用来增强类的功能、修改方法的行为,或者修改类的元数据等…...

堆优化版本的Prim

prim和dijkstra每轮找最小边的松弛操作其实是同源的&#xff0c;因而受dijkstra堆优化的启发&#xff0c;那么prim也可以采用小根堆进行优化。时间复杂度也由 O ( n 2 ) O(n^2) O(n2)降为 O ( n l o g n ) O(nlogn) O(nlogn)。 测试一下吧&#xff1a;原题链接 #include <i…...

Ubuntu上安装MySQL并且实现远程登录

目录 下载网络工具 查看网络连接 更新系统软件包&#xff1b; 安装mysql数据库 查看mysql数据库状态 以数字ip形式显示mysql的监听状态。&#xff08;默认监听端口是3306&#xff09; 查看安装mysql数据库时系统创建的目录信息。 根据查询到的系统用户名以及随机密码&a…...

蓝桥杯每日真题 - 第21天

题目&#xff1a;(空间) 题目描述&#xff08;12届 C&C B组A题&#xff09; 解题思路&#xff1a; 转换单位&#xff1a; 内存总大小为 256MB&#xff0c;换算为字节&#xff1a; 25610241024268,435,456字节 计算每个整数占用空间&#xff1a; 每个 32 位整数占用…...

(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验一(下)----空间数据的编辑与处理(超超超详细!!!)

续上篇博客&#xff08;长期更新&#xff09;《零基础入门 ArcGIS(ArcMap) 》实验一&#xff08;上&#xff09;----空间数据的编辑与处理&#xff08;超超超详细&#xff01;&#xff01;&#xff01;&#xff09;-CSDN博客 继续更新 目录 什么是拓扑&#xff1f; 1.3.5道路…...

NLP论文速读(CVPR 2024)|使用DPO进行diffusion模型对齐

论文速读|Diffusion Model Alignment Using Direct Preference Optimization 论文信息&#xff1a; 简介&#xff1a; 本文探讨的背景是大型语言模型&#xff08;LLMs&#xff09;通过人类比较数据和从人类反馈中学习&#xff08;RLHF&#xff09;的方法进行微调&#xff0c;以…...

操作系统——揭开盖子

计算机执行时——取指执行 es:bx等于从0x9000开始&#xff0c;到0x90200结束...

如何在 React 项目中应用 TypeScript?应该注意那些点?结合实际项目示例及代码进行讲解!

在 React 项目中应用 TypeScript 是提升开发效率、增强代码可维护性和可读性的好方法。TypeScript 提供了静态类型检查、自动补全和代码提示等功能&#xff0c;这对于 React 开发者来说&#xff0c;能够帮助早期发现潜在的 bug&#xff0c;提高开发体验。 1. 项目初始化 在现…...

C++学习第四天

创作过程中难免有不足&#xff0c;若您发现本文内容有误&#xff0c;恳请不吝赐教。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、计算类对象的大小 #include<iostream> using namespace std;class Date { public:void Init(int year, in…...

【从零开始的LeetCode-算法】3232. 判断是否可以赢得数字游戏

给你一个 正整数 数组 nums。 Alice 和 Bob 正在玩游戏。在游戏中&#xff0c;Alice 可以从 nums 中选择所有个位数 或 所有两位数&#xff0c;剩余的数字归 Bob 所有。如果 Alice 所选数字之和 严格大于 Bob 的数字之和&#xff0c;则 Alice 获胜。 如果 Alice 能赢得这场游…...

一种简单高效的RTSP流在线检测方法,不需要再过渡拉流就可以获取设备状态以及对应音视频通道与编码格式

平台如何检测一路RTSP流是否在线&#xff1f; 在之前的流媒体平台方案中&#xff0c;我们都是通过定时RTSP拉流的方式&#xff0c;走一个完整的RTSP流程&#xff1a;包括OPTIONS、DESCRIBE、SETUP、PLAY、RTP收流&#xff0c;这种方式去取流&#xff0c;然后取到流之后进行流解…...

24/11/22 项目拆解 艺术风格转移

我们有时候想把两种艺术风格整合&#xff0c;创造更具艺术特色的艺术品&#xff0c;人很难办到&#xff0c;但是人工智能可以,比如下面将艺术画的风格转移到照片上。 我们先来初步了解一下实现上述功能的数学原理 所谓艺术风格&#xff0c;其实就是边缘&#xff0c;颜色&#…...

数字赋能,气象引领 | 气象景观数字化服务平台重塑京城旅游生态

在数字化转型的浪潮中&#xff0c;旅游行业正以前所未有的速度重塑自身&#xff0c;人民群众对于高品质、个性化旅游服务需求的日益增长&#xff0c;迎着新时代的挑战与机遇&#xff0c;为开展北京地区特色气象景观预报&#xff0c;打造“生态气象旅游”新业态&#xff0c;助推…...

关于Redux的学习(包括Redux-toolkit中间件)

目录 什么是 Redux &#xff1f; 我为什么要用 Redux &#xff1f; 我什么时候应该用 Redux &#xff1f; Redux 库和工具 React-Redux Redux Toolkit Redux DevTools 拓展 一个redux小示例 代码示例(很有用)&#xff1a; Redux 术语 Actions Reducers Store Dis…...

【无人机】

GJI Mini 4 Pro学习 首次飞行使用 01 开箱 打开长飞套装 依次取出产品及配件 飞行器、DJI RC - N2&#xff08;DJI RC 2&#xff09;、桨叶/螺丝、云台保护罩、束桨器、电池、螺丝刀、USB-C快接线、单肩包、USB-C数据线、充电管家 02 准备飞行器 取下束桨器&#xff0c;…...

Zabbix7.0.6的容器镜像准备

准备Zabbix7.0.6部署所需的容器镜像。 更新时间&#xff1a;20241122 一、准备数据库镜像 1、核对版本支持 根据Zabbix官网文档requirements 可知&#xff0c;当前最新的Zabbix 7.0.6对PostgreSQL数据库的要求如下&#xff1a; support for PostgreSQL versions:- 17.X …...

利用 GitHub 和 Hexo 搭建个人博客【保姆教程】

利用 GitHub 和 Hexo 搭建个人博客 利用 GitHub 和 Hexo 搭建个人博客一、前言二、准备工作&#xff08;一&#xff09;安装 Node.js 和 Git&#xff08;二&#xff09;注册 GitHub 账号 三、安装 Hexo&#xff08;一&#xff09;创建博客目录&#xff08;二&#xff09;安装 H…...

React第四节 组件的三大属性之state

前言 状态 state适用于类式组件中&#xff0c;而再函数式组件中需要使用 useState HOOK 模拟状态; React的组件就是一个状态机&#xff0c;通过与用户的交互&#xff0c;实现不同的状态&#xff0c;根据不同的状态展现出不一样的UI视图 并不是组件中所有的属性 都是组件的状态…...

MongoDB进阶篇-索引(索引概述、索引的类型、索引相关操作、索引的使用)

文章目录 1. 索引概述2. 索引的类型2.1 单字段索引2.2 复合索引2.3 其他索引2.3.1 地理空间索引&#xff08;Geospatial Index&#xff09;2.3.2 文本索引&#xff08;Text Indexes&#xff09;2.3.3 哈希索引&#xff08;Hashed Indexes&#xff09; 3. 索引相关操作3.1 查看索…...

使用FFmpeg实现视频与GIF的画中画效果

用FFmpeg命令行工具将GIF动画作为画中画&#xff08;Picture-in-Picture&#xff0c;简称PiP&#xff09;叠加到视频上。FFmpeg是一个强大的多媒体框架&#xff0c;能够处理几乎所有格式的音频和视频文件。通过这个教程&#xff0c;你将学会如何将一个小的GIF动画循环播放&…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...