typescript 模块_如何使用TypeScript装饰器编写模块化代码并解决横切关注点

typescript 模块

If you have worked with a framework like Angular you have used syntax such as @Component, @HostListenerand and @viewchild. These are known as TypeScript decorators. They are one of the most powerful yet under-used features of TypeScript.

如果您使用过类似Angular的框架,则可以使用诸如@Component @HostListenerand@Component @HostListenerand@viewchild @Component语法。 这些被称为TypeScript装饰器。 它们是TypeScript最强大但未充分使用的功能之一。

In this article we will discuss:

在本文中,我们将讨论:

  • What decorators are

    什么是装饰
  • How to implement your own decorators

    如何实现自己的装饰器
  • Leveraging decorators to write clean modular code

    利用装饰器编写干净的模块化代码
  • Aspect Oriented Programming and decorators

    面向方面的编程和装饰器
  • Cross-cutting-concerns and solving them with decorators

    横切问题,并用装饰器解决

首先-什么是装饰器? (First - What is a Decorator?)

A decorator is a function that allows us to annotate our code or hook into its behavior (similar to meta-programming).

装饰器是允许我们注释代码或挂钩其行为的函数(类似于元编程)。

Decorators are very good at creating abstractions. When a piece of logic needs to be duplicated in many places we can use a decorator for it. Decorators also solve problems that are hard to solve with inheritance (more on this later).

装饰者非常擅长创建抽象。 当需要在许多地方复制逻辑时,可以使用装饰器。 装饰器还解决了难以通过继承解决的问题(稍后会详细介绍)。

There are 4 types of Decorators in TypeScript and they are as follows:

TypeScript中有4种类型的Decorator,它们如下:

类装饰器 (Class Decorators)

A Class Decorator is declared before a class declaration. A class decorator is applied to the constructor of the class and can be used to observe, modify, or replace a class definition.

在类声明之前声明类装饰器。 类装饰器应用于类的构造函数,可用于观察,修改或替换类定义。

Here’s an example:

这是一个例子:

@robot
class Greeter {
 private greeting: string;
 constructor(message: string) {
   this.greeting = message;
 }
 greet() {
   return "Hello, " + this.greeting;
 }
}
 
function robot<T extends { new (...args: any[]): {} }>(constructor: T) {
 return class extends constructor {
   greeting = "from  Robot :-{";
 };
}
let k = new Greeter("shadid");
console.log(k.greet());

In this example we are overriding the constructor of our Greeter class. Our robot decorator function is just like a normal function. However, it takes in a class constructor as an argument. We can use this constructor that is being passed in as a parameter and override its functionality.

在此示例中,我们将重写Greeter类的构造函数。 我们的robot装饰器功能就像普通功能一样。 但是,它将类构造函数作为参数。 我们可以使用此构造函数作为参数传入,并覆盖其功能。

方法装饰器 (Method Decorator)

A Method Decorator is declared before a method declaration. It is applied to the Property Descriptor for the method, and can be used to observe, modify, or replace a method definition.

在方法声明之前声明方法装饰器。 它应用于方法的属性描述符,并且可以用于观察,修改或替换方法定义。

Here’s an example:

这是一个例子:

declare type MethodDecorator = <T>(
 target: Object,
 propertyKey: string | symbol,
 descriptor: TypedPropertyDescriptor<T>
) => TypedPropertyDescriptor<T> | void;
 
class Robot {
 greeting: string;
 constructor(message: string) {
   this.greeting = message;
 }
 
 @logMethod("Greet")
 greet() {
   return "Hello, " + this.greeting;
 }
}
 
function logMethod(message: string): MethodDecorator {
 console.log(`${message} evaluated`);
 return function(
   target: Object,
   propertyKey: string,
   descriptor: PropertyDescriptor
 ): void {
   console.log(`${message} called`);
 };
}
 
let bot = new Robot("I am robo, nice to meet you :)");
console.log(bot.greet());

Here we first defined a MethodDecorator type. We created a method decorator called logMethod. This decorator function is a factory function that returns another function of type MethodDecorator. While using decorators it is a common practice to use a factory function. The returned function is where we will usually apply our logic.

在这里,我们首先定义了MethodDecorator类型。 我们创建了一个名为logMethod的方法装饰器。 此装饰器函数是一个工厂函数,它返回另一个类型为MethodDecorator的函数。 使用装饰器时,通常使用工厂功能。 返回的函数通常是我们应用逻辑的地方。

物业装饰 (Property Decorator)

The Property Decorator is applied to a Property definition. You are probably noticing a pattern already 😊. Below is an example:

属性装饰器应用于属性定义。 您可能已经注意到一种模式😊。 下面是一个示例:

class Greeter {
 @logGreet("Logging Greetings")
 greeting: string;
 ....
}
 
function logGreet(formatString: string) {
 console.log(formatString);
}

参数装饰器 (Parameter Decorator)

As the name suggests, this decorator is applied to the parameters of methods. Below is an example:

顾名思义,此装饰器应用于方法的参数。 下面是一个示例:

class Greeter {
 ...
 public makeRobotNoise(
   @logParameter("Param for method robot noise") person: Person
 ) {
   this._directReports.push(person);
 }
}
 
function logParameter(message: string): ParameterDecorator {
 console.log(`${message} logParam factory`);
 return function(
   target: Object,
   propertyKey: string,
   parameterIndex: number
 ): void {
   console.log(`${message} called from return function`);
 };
}

These are some of the basic examples of decorators. Now let's work though a real world project together where we can implement decorators to cut down repeated functionality in our code.

这些是装饰器的一些基本示例。 现在,让我们一起完成一个真实的项目,在这里我们可以实现装饰器,以减少代码中的重复功能。

应用我们所学 (Applying what we've learned)

如何实现自己的装饰器 (How to implement your own decorators)

We will be building a REST api server with Node.js, Express and TypeScript. We will structure our code for scalability and proper testing. We will also look at a concept called Aspect Oriented Programming (AOS) and apply a layered architecture.

我们将使用Node.js,Express和TypeScript构建REST api服务器。 我们将为可伸缩性和适当的测试构造代码。 我们还将研究称为面向方面编程(Aspect Oriented Programming,AOS)的概念,并应用分层体系结构。

Alright let's dive in.

好吧,让我们潜入。

Get the starter code from the following directory. I have setup a TypeScript project with Express for you to follow along.

从以下目录获取入门代码。 我已经使用Express设置了TypeScript项目,以供您遵循。

https://github.com/Shadid12/entity-framework/tree/intro_1

https://github.com/Shadid12/entity-framework/tree/intro_1

Let's go over the project together.

让我们一起来看一下这个项目。

src/app.ts

src/app.ts

import APIServer from "./APIServer";
 
export const apiServer = new APIServer();
 
apiServer.start();

app.ts is our application entry point. You can see that we are creating an instance of the APIServer class and calling the start() method. APISe

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值