【问题标题】:Define a decorator guard in typescript在 typescript 中定义一个装饰器守卫
【发布时间】:2017-08-11 18:05:42
【问题描述】:

假设您有实现某个装饰器的类:

@Component
class A

@Component
class B

如果你想要一个变量来保存其中一些类的类本身,它会有什么类型?

componentClass: typeof A | typeof B;

但是你是否已经在想:如果你有很多类,枚举类不是一个好习惯,当你不知道它们时,它甚至不是一个选择。

所以剩下的选项是(编辑:因为打字稿不允许typeof泛型)

componentClass: any;

但这也不好!


我想为此定义一个类型保护,因此我可以将any 类型替换为可以实际检查对象是否具有@Component 装饰器的类型,因此可以将其声明为这个:

componentClass: ComponentClass;

只是一个想法

我认为最好的方法是为它定义一个类型,并在其中定义守卫。 但这是不可能的

@HasDecorator("Component")
type ComponentClass = any;

希望看到你的想法来解决这个问题。谢谢!

【问题讨论】:

  • 你不能那样做。装饰器是在运行时调用的函数,而类型系统是在编译时调用的。

标签: typescript reflect-metadata


【解决方案1】:

如果你有代表Component 的不同类,那么为什么不为它们都创建一个基类:

abstract class ComponentClass { ... }

@Component
class A extends ComponentClass { ... }

@Component
class B extends ComponentClass { ... }

那么你就有了所有这些类的类型,并且不需要类型别名。
它对装饰器本身也很有用:

function Component(ctor: { new(): ComponentClass }) {}

甚至:

function Component<T extends ComponentClass>(ctor: { new(): T }) {}

编辑

当然,你也可以用接口做类似的事情:

interface ComponentClass { }

@Component
class A implements ComponentClass { }

@Component
class B implements ComponentClass { }

第二次编辑

如果你想传递ComponentClassA,或B等),那么你可以这样做:

function fn(cls: typeof ComponentClass) { ... }

fn(A);

或者

function fn<T extends ComponentClass>(cls: { new(): T }) { ... }

fn(B);

(code in playground)

【讨论】:

  • 请检查我的编辑。我说变量包含类本身,但忘记在声明中添加typeof,如下所示:componentClass: typeof A。您的建议也是我的第一种方法,但是 typescript 不支持 typeof 泛型,所以我做不到。
  • 为什么需要typeof A?你将如何使用它?
  • 能够将A 传递给函数,而不是它的实例。我是动态创建组件,需要知道每个要创建的类,所以需要传递一个类型。
  • 这不会给出错误Argument of type 'typeof A' is not assignable to parameter of type 'typeof ComponentClass'吗?这就是我所说的 typeof generic。如果你没有那个错误,那么最新版本的 typescript 增加了对它的支持。
  • 我的代码中根本没有使用typeof。添加了指向 Playground 中代码的链接。无论如何,如果你这样做,你不应该得到错误。
猜你喜欢
  • 2020-07-11
  • 2020-09-04
  • 2018-01-31
  • 2015-10-23
  • 2019-08-14
  • 2018-07-20
  • 2023-03-17
  • 2021-04-22
  • 2012-10-30
相关资源
最近更新 更多