打字稿装饰器与类继承

Posted

技术标签:

【中文标题】打字稿装饰器与类继承【英文标题】:Typescript decorators vs class inheritance 【发布时间】:2016-12-05 20:54:04 【问题描述】:

我对打字稿装饰器以及它们的解释方式有点困惑。假设他们通过将元数据与它相关联来“装饰”一个类。我似乎无法真正理解元数据如何与类的实例相关联的概念。以角度 2 为例。

 @Component(
       
          selector:...
       
    ) 


    export class foo  ... 

目前据我了解,angular 将实例化类 foo 并以某种方式将实例与装饰器的参数相关联,以便它可以提供服务、指令和模板。所有这些似乎也可以通过类继承来实现。如果我有一个 Component 类并让我的组件扩展该类,为什么不能 angular 然后在它以与 props 反应的方式引导时提供这些参数,并在此使用场景中完全摆脱装饰器。

class Component  ...  //say this has members such as selector, services, directives, etc..

class Foo extends Component  ... 

然后你会在引导/运行时用这个实例化它

new Foo(ElementName, Directives, Services, etc..)

使用 react 从技术上讲,这就是幕后发生的事情。您派生了组件并实现了它的方法。如果在实例化的时候需要传递信息,那么就传入 props 对象。

请赐教。

【问题讨论】:

【参考方案1】:

据我所知,主要原因是为了便于静态评估。使用继承,您需要执行 TS(或转译的 JS)代码来获取信息。

静态评估此元数据允许工具将其用于自动完成和模板中的所有类型的 lint 检查,以及构建设计器和其他工具,从而更轻松地构建 Angular 应用程序。

离线模板编译器也使用此元数据。

【讨论】:

【参考方案2】:

这段代码看起来确实很相似:

import  Component  from '@angular/core';
export class AppComponent extends Component 

VS:

import  Component  from '@angular/core';
@Component()
export class AppComponent  

您可以通过不同的方式执行inheritance in JS - 如果您选择使用Class syntactic sugar 并希望使用extends 语法来实现继承,那么您将被锁定在single inheritance - 所以每个类都可以只继承另一个类。

使用@Decorators 可以将多个 行为附加到一个类,从而创建multiple inheritance 与mixins 不同。正如 Günter Zöchbauer 指出的那样,装饰器更容易静态评估,而继承必须在运行时评估(即,如果编译器想知道特定子类的行为类型)。

我将 @Decorators 视为 composition - 因为它们基本上是函数,所以我将它们视为与 higher-order functions 相同,所以它就像在做类似的事情,但更具可读性:

import  Component  from '@functionalComponent/core';
let myComponent = function()  return hello: 'world'
let AppComponent = Component(myComponent())

不要忘记Class 本质上是纯 JS 对象,由构造函数创建/实例化。

import  Component  from '@constructedComponent/core';
let MyComponent = function() this.hello ='world'
let AppComponent = new Component(new MyComponent)

或者甚至“更低”,把它想象成纯粹的物体:

import  Component  from '@objectComponent/core';
let MyComponent = this.hello ='world'
let AppComponent = Component.augment(MyComponent)

一般来说,JS 的原型和函数特性非常强大,允许通过调用函数和更改对象来混合行为。当您切换到 Class 语法时,情况会发生变化——此时您应该坚持称为 Composition over inheritance 的 OOP 设计原则,而 decorators 是一种用易于阅读的语法表达组合的巧妙方法:

Difference between the Composite Pattern and Decorator Pattern?

来自***:

装饰器的使用可能比子类化更有效,因为可以在不实例化全新对象的情况下增强对象的行为。

【讨论】:

以上是关于打字稿装饰器与类继承的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有角度依赖注入的打字稿继承

装饰器与继承

使用静态方法的打字稿继承

打字稿类型定义 - 继承

类装饰器上的打字稿文档-返回“类扩展构造函数”的函数

typescript 打字稿接口继承