您可以将带有装饰器的 Typescript 类导出为普通类(没有装饰器)吗?

Posted

技术标签:

【中文标题】您可以将带有装饰器的 Typescript 类导出为普通类(没有装饰器)吗?【英文标题】:Can you export a Typescript class with decorators as a plain class (without decorators)? 【发布时间】:2020-04-23 01:26:11 【问题描述】:

假设我有这样的课程:

import  Injectable  from '@nestjs/common';
import  IsString  from 'class-validator';
import  prop  from '@typegoose/typegoose';

@Injectable()
export class Human

    @prop( unique: true )
    @IsString()
    readonly name: string;

问题是:我可以导出这个类,以便接收端在没有装饰器的情况下得到它,如下所示:

class Human

    readonly name: string;

我想导出这个类(它对装饰器有其他依赖项),以便导入它的文件不需要这些装饰器使用的依赖项,例如nestjs、class-validator和typegoose。

我试图不写出“只读名称:字符串;”不止一次。

【问题讨论】:

不要认为没有某种预处理是可能的。您可以导出从该类派生的类型或接口,但不能使用它们来实例化对象。为此,您需要一个构造函数,但是您还必须再次编写属性。 @zett42 当我说我只想写出一次属性时,我的意思是定义类/接口。不是在我创建新对象时。当我创建一个接口类型的新对象时,我希望该接口在我创建新对象时强制我实现该接口。这很好。我可以忍受这一点,我也可以忍受为一个类添加一个构造函数。那是正常的面向对象的东西。话虽如此,您能否向我展示一个“导出从类派生的类型或接口”的示例,该示例会留下装饰器依赖关系? @zett42 抱歉,我问了一个例子,因为我已经尝试过这样做但它不起作用,但我知道为什么我可以将它作为没有依赖关系的类型导出。哎呀!谢谢你的评论!如果您不介意,我将通过示例将其发布为答案。 提取接口:export interface IHuman extends Human ;。随意使用它作为您的答案。 【参考方案1】:

所以我想通了,部分归功于 zett42。

您可以在打字稿中定义type,因此,如果您只是创建一个与类相等的类型,然后导出该类型,您将有效地导出该类定义而无需装饰器。你也可以用interfaces 来做,但类型似乎更干净。但是我不确定类型的行为是否与接口相同,是时候阅读 Typescript 文档了!

有类型:

export type THuman = Human;

带接口:

export interface IHuman extends Human 

【讨论】:

export type 正在为该类创建一个类型别名,这意味着同一个类包括装饰 AFAIK,您不会丢弃它们。 export interface I extends Class 应该是正确答案。 AFAIK 接口扩展只复制对象原型上的公共成员定义。

以上是关于您可以将带有装饰器的 Typescript 类导出为普通类(没有装饰器)吗?的主要内容,如果未能解决你的问题,请参考以下文章

关于何时在 TypeScript 中调用装饰器的困惑

如何在 TypeScript 中使用装饰器

TypeScript(21): 装饰器

TypeScript 装饰器的执行原理

使用带有 Vue 和 TypeScript 类装饰器语法的外部定义组件

Python进阶装饰器(Decorator)