理解 TypeScript 中的装饰器:第一原理方法
本篇文章给大家分享《理解 TypeScript 中的装饰器:第一原理方法》,覆盖了文章的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。

typescript 中的装饰器提供了一种强大的机制来修改类、方法、属性和参数的行为。虽然它们看起来像是一种现代的便利,但装饰器植根于面向对象编程中成熟的装饰器模式。通过抽象日志记录、验证或访问控制等常见功能,装饰器允许开发人员编写更清晰、更易于维护的代码。
在本文中,我们将从首要原则探索装饰器,分解其核心功能,并从头开始实现它们。在此过程中,我们将了解一些实际应用程序,这些应用程序展示了装饰器在日常 typescript 开发中的实用性。
什么是装饰器?
在 typescript 中,装饰器只是一个可以附加到类、方法、属性或参数的函数。此函数在设计时执行,使您能够在代码运行之前更改代码的行为或结构。装饰器支持元编程,允许我们在不修改原始逻辑的情况下添加额外的功能。
让我们从一个方法装饰器的简单示例开始,该示例记录调用方法的时间:
function log(target: any, propertykey: string, descriptor: propertydescriptor) {
const originalmethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`calling ${propertykey} with arguments: ${args}`);
return originalmethod.apply(this, args);
};
return descriptor;
}
class example {
@log
greet(name: string) {
return `hello, ${name}`;
}
}
const example = new example();
example.greet('john');
这里,日志装饰器包装了greet方法,在执行之前记录其调用和参数。此模式对于将日志记录等横切关注点与核心逻辑分离非常有用。
装饰器如何工作
typescript 中的装饰器是接受与其所装饰的项目相关的元数据的函数。基于这些元数据(如类原型、方法名称或属性描述符),装饰器可以修改行为甚至替换被装饰的对象。
装饰器的类型
装饰器可以应用于各种目标,每个目标都有不同的目的:
- 类装饰器:接收类构造函数的函数。
function classdecorator(constructor: function) {
// modify or extend the class constructor or prototype
}
- 方法装饰器:接收目标对象、方法名称和方法描述符的函数。
function methoddecorator(target: any, propertykey: string, descriptor: propertydescriptor) {
// modify the method's descriptor
}
- 属性装饰器:接收目标对象和属性名称的函数。
function propertydecorator(target: any, propertykey: string) {
// modify the behavior of the property
}
- 参数装饰器:接收目标、方法名称和参数索引的函数。
function parameterdecorator(target: any, propertykey: string, parameterindex: number) {
// modify or inspect the method's parameter
}
将参数传递给装饰器
装饰器最强大的功能之一是它们接受参数的能力,允许您自定义它们的行为。例如,让我们创建一个方法装饰器,它根据参数有条件地记录方法调用。
function logconditionally(shouldlog: boolean) {
return function (target: any, propertykey: string, descriptor: propertydescriptor) {
const originalmethod = descriptor.value;
descriptor.value = function (...args: any[]) {
if (shouldlog) {
console.log(`calling ${propertykey} with arguments: ${args}`);
}
return originalmethod.apply(this, args);
};
return descriptor;
};
}
class example {
@logconditionally(true)
greet(name: string) {
return `hello, ${name}`;
}
}
const example = new example();
example.greet('typescript developer');
通过将 true 传递给 logconditionally 装饰器,我们确保该方法记录其执行情况。如果我们传递 false,则跳过日志记录。这种灵活性是使装饰器具有多功能性和可重用性的关键。
装饰器的实际应用
装饰器在许多库和框架中都有实际用途。以下是一些值得注意的示例,说明了装饰器如何简化复杂的功能:
- 类验证器中的验证:在数据驱动的应用程序中,验证至关重要。 class-validator 包使用装饰器来简化验证 typescript 类中字段的过程。
import { isemail, isnotempty } from 'class-validator';
class user {
@isnotempty()
name: string;
@isemail()
email: string;
}
在此示例中,@isemail 和 @isnotempty 装饰器确保电子邮件字段是有效的电子邮件地址并且名称字段不为空。这些装饰器消除了手动验证逻辑的需要,从而节省了时间。
- 使用 typeorm 进行对象关系映射:装饰器广泛用于 typeorm 等 orm 框架中,用于将 typescript 类映射到数据库表。此映射是使用装饰器以声明方式完成的。
import { entity, column, primarygeneratedcolumn } from 'typeorm';
@entity()
class user {
@primarygeneratedcolumn()
id: number;
@column()
name: string;
@column()
email: string;
}
这里,@entity、@column 和 @primarygeneeratedcolumn 定义了 user 表的结构。这些装饰器抽象了 sql 表创建的复杂性,使代码更具可读性和可维护性。
- angular 依赖注入:在 angular 中,装饰器在管理服务和组件方面发挥着关键作用。 @injectable 装饰器将一个类标记为可以注入其他组件或服务的服务。
@injectable({
providedin: 'root',
})
class userservice {
constructor(private http: httpclient) {}
}
在这种情况下,@injectable 装饰器向 angular 的依赖注入系统发出信号,表明应在全局范围内提供 userservice。这允许跨应用程序无缝集成服务。
实现你自己的装饰器:分解
装饰器的核心就是函数。让我们分解一下从头开始创建装饰器的过程:
类装饰器
类装饰器接收类的构造函数,可以用来修改类原型,甚至替换构造函数。
function addtimestamp(constructor: function) {
constructor.prototype.timestamp = new date();
}
@addtimestamp
class myclass {
id: number;
constructor(id: number) {
this.id = id;
}
}
const instance = new myclass(1);
console.log(instance.timestamp); // outputs the current timestamp
方法装饰器
方法装饰器修改方法描述符,允许您更改方法本身的行为。
function logexecutiontime(target: any, propertykey: string, descriptor: propertydescriptor) {
const originalmethod = descriptor.value;
descriptor.value = function (...args: any[]) {
const start = performance.now();
const result = originalmethod.apply(this, args);
const end = performance.now();
console.log(`${propertykey} executed in ${end - start}ms`);
return result;
};
return descriptor;
}
class service {
@logexecutiontime
execute() {
// simulate work
for (let i = 0; i < 1e6; i++) {}
}
}
const service = new service();
service.execute(); // logs the execution time
物业装修师
属性装饰器允许您拦截属性访问和修改,这对于跟踪更改非常有用。
function trackChanges(target: any, propertyKey: string) {
let value = target[propertyKey];
const getter = () => value;
const setter = (newValue: any) => {
console.log(`${propertyKey} changed from ${value} to ${newValue}`);
value = newValue;
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
});
}
class Product {
@trackChanges
price: number;
constructor(price: number) {
this.price = price;
}
}
const product = new Product(100);
product.price = 200; // Logs the change
结论
typescript 中的装饰器允许您以干净、声明的方式抽象和重用功能。无论您使用验证、orm 还是依赖注入,装饰器都有助于减少样板文件并保持代码模块化和可维护性。从第一原理出发了解它们的工作原理可以更轻松地充分利用它们的潜力并根据您的应用程序定制解决方案。
通过更深入地了解装饰器的结构和实际应用,您现在已经了解了它们如何简化复杂的编码任务并简化各个领域的代码。
文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《理解 TypeScript 中的装饰器:第一原理方法》文章吧,也可关注golang学习网公众号了解相关技术文章。
Nodejs Util 模块中的一些有用的函数
- 上一篇
- Nodejs Util 模块中的一些有用的函数
- 下一篇
- 前端 UI 组件
-
- 文章 · 前端 | 3小时前 |
- HTML目录栏制作方法:锚点导航树形菜单教程
- 102浏览 收藏
-
- 文章 · 前端 | 3小时前 |
- CSS背景图自适应容器填充技巧
- 420浏览 收藏
-
- 文章 · 前端 | 3小时前 |
- MongoDB日期查询方法与注意事项
- 278浏览 收藏
-
- 文章 · 前端 | 3小时前 |
- CSSFlex与MediaQuery响应式实战指南
- 156浏览 收藏
-
- 文章 · 前端 | 4小时前 |
- CSRF原理与令牌添加详解
- 225浏览 收藏
-
- 文章 · 前端 | 4小时前 |
- Flexbox居中间距技巧:gap属性详解
- 250浏览 收藏
-
- 文章 · 前端 | 4小时前 |
- Set与Map算法选择优化指南
- 446浏览 收藏
-
- 文章 · 前端 | 4小时前 | 样式控制 CSS伪类 动态内容 唯一子元素 :only-child
- CSSonly-child选择器使用方法
- 228浏览 收藏
-
- 文章 · 前端 | 4小时前 |
- UTC时间转换技巧与时区处理方法
- 360浏览 收藏
-
- 文章 · 前端 | 4小时前 |
- 回溯法解八皇后问题全解析
- 165浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3204次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3417次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3446次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4555次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3824次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览

