首页 > 解决方案 > 使用类表达式时是否支持循环引用?

问题描述

在使用类表达式时,我在使用循环引用时遇到了一些问题。我正在动态生成类并尝试正确键入它们。

循环引用适用于类声明。

我正在尝试做的事情可能吗?

// Works
class X {
  y?: Y;
}
class Y {
  x?: X;
}

// Works without circular ref
const I = class {
};
const J = class {
  i?: typeof I;
};


// Doesn't work  with circular ref
const A = class {
  b?: typeof B;
};
const B = class {
  a?: typeof A;
};

打字稿游乐场


上下文更新

我正在尝试创建一个从给定的“模型定义”生成类的函数。此模型定义具有布尔、字符串、数字等类型,但也可能与另一个模型有关系。

只要不引入循环引用,它就类型而言可以正常工作。

这个操场说明了我想要完成的事情。

标签: typescriptes6-class

解决方案


在对 TypeScript 语言规范进行了一些研究之后,我认为不幸的是,无法将循环类型引用与类表达式一起使用。

我无法根据您提供的信息判断您的一般方法是否正确 - 例如,如果您真的需要类表达式、动态模型或者它是 XY 问题。这本身就是另一个话题。我在这里尝试回答,为什么您使用循环类型引用和类表达式的方法会产生编译错误。

当类表达式A和/B相互引用时,您使用运算符创建类型别名。对于类型别名,规范说:typeof Atypeof Btypeof

类型别名中指定的类型依赖于该类型别名是错误的。关联

但是,还声明了以下内容:

请注意,对象类型文字、函数类型文字和构造函数类型文字不依赖于其中引用的类型,因此允许通过类型别名循环引用自己。关联

我以这种方式解释该语句:如果您将模型引用包装/替换为上述类型文字之一,则可以使用循环引用。

修改后的游乐场

在此示例中,我将您的模型类构造包装在工厂方法/函数类型文字中。它仅用于演示目的和作品,请随意解释它自己的方式。

它假设您可以FieldDescriptor稍微调整:

type FieldDescriptor = keyof MapSchemaTypes | (() => ModelConstructor<any>);

关于类声明:我想它们在您的示例中工作,因为类声明和接口被支持为Recursive Types。另请参阅TypeScript 首席开发人员的此声明

希望,这对您的情况有所帮助。


推荐阅读