Reinforced.Typings 不会为具有 UseModules(true, false) 的类型生成 FQN
Reinforced.Typings does not produce FQN for types with UseModules(true, false)
总结:
我有两个项目的简单解决方案,例如ProjA 和 ProjB。在 ProjA 中,我已经指定了我的自定义 RTConfigure
方法,以便使用 Reinforeced.Typings 工具将 C# 翻译成 TypeScript 代码来流畅地配置翻译过程。在 ProjB 中,我定义了用于翻译的 C# ViewModel classes。
问题:
在 ProjB 中,我在三个单独的文件 中定义了三个 classes,每个都属于它们特定的命名空间 。通过调用例如使用全局构建器配置时builder.UseModules(true, false)
生成的代码不包括引用关键字 extends
之后的类型的转换类型和指定为另一个 class 成员的类型(属于与使用的成员类型不同的另一个命名空间。
例如:
- ProjB.Ns1.Class1
- ProjB.Ns2.Class2
- ProjB.Ns3.Class3
所有三个 classes 只定义了两个简单的道具,其中 Class3 有点不同,包含一个额外的 属性 类型为 Class1。 Class2继承自Class1。
示例代码如下:
// Class1.cs
namespace ReinforcedTypings.DifferentNamespaces.Ns1
{
public class Class1
{
public int AnIntegerPropNs1 { get; set; }
public string AStringPropNs1 { get; set; }
}
}
// Class2.cs
using ReinforcedTypings.DifferentNamespaces.Ns1
namespace ReinforcedTypings.DifferentNamespaces.Ns2
{
public class Class2 : Class1
{
public int AnIntegerPropNs2 { get; set; }
public string AStringPropNs2 { get; set; }
}
}
// Class3.cs
using ReinforcedTypings.DifferentNamespaces.Ns1
namespace ReinforcedTypings.DifferentNamespaces.Ns3
{
public class Class3
{
public int AnIntegerPropNs3 { get; set; }
public string AStringPropNs3 { get; set; }
public Class1 AClass1PropNs3 { get; set; }
}
}
configure方法很简单,定义如下:
public static class RTConfig
{
public static void Configure(ConfigurationBuilder builder)
{
var types = typeof(ReinforcedTypings.DifferentNamespaces.Ns1.Class1).Assembly.GetTypes().ToList();
builder.ExportAsClasses(types.Where(x => x.IsClass), c => c.WithAllFields().WithAllMethods().WithAllProperties());
builder.Global(c => c.UseModules(true, false));
// ^ commenting out this line will also cause a different error
}
}
我使用 .xml 配置文件通过将以下选项 (false) 设置为:
来指定翻译应全部生成一个文件
<RtDivideTypesAmongFiles>false</RtDivideTypesAmongFiles>
...这会导致以下 TypeScript 代码(translated.ts 在 .xml 配置文件中设置):
export namespace ReinforcedTypings.DifferentNamespaces.Ns3 {
export class Class3
{
public AnIntegerPropNs3: number;
public AStringPropNs3: string;
public AClass1PropNs3: Class1; // <- error here
}
}
export namespace ReinforcedTypings.DifferentNamespaces.Ns2 {
export class Class2 extends Class1 // <- error here
{
public AnIntegerPropNs2: number;
public AStringPropNs2: string;
}
}
export namespace ReinforcedTypings.DifferentNamespaces.Ns1 {
export class Class1
{
public AnIntegerPropNs1: number;
public AStringPropNs1: string;
}
}
请注意,Class1
类型在扩展后以及 Class3
的已翻译 属性 成员 private AClass1PropNs3: Class1;
中缺少其名称的完整命名空间符号。
这会导致 TypeScript 出现问题,因为由于未指定类型的完整(命名空间)路径名而找不到这些类型。
观察到的附带问题:
当不使用 UseModules 时,如果您注释掉该行,则会在翻译的 TypeScript 代码中发现另一个问题,这是由于翻译代码的顺序,即找不到 Class1
在 Class3
中,因为它在声明之前使用。
结论:
我没有深入研究 RT 的源代码,但我怀疑 UseModules(true, false)
存在一个问题,其中第二个参数明确声明不丢弃命名空间,另一个问题是关于获取的代码的顺序输出。无论如何,将第二个参数值设置为 false 会期望始终随处都有所用类型的 FQN。如果我错误地使用了此配置道具,那么我建议拥有这样的全局配置将对 all/desired 类型强制使用 FQN 大有裨益。
肯定是FQN问题是RT的bug,1.4.6版本已经修复
关于附带问题:参见this GitHub Discussion
总结:
我有两个项目的简单解决方案,例如ProjA 和 ProjB。在 ProjA 中,我已经指定了我的自定义 RTConfigure
方法,以便使用 Reinforeced.Typings 工具将 C# 翻译成 TypeScript 代码来流畅地配置翻译过程。在 ProjB 中,我定义了用于翻译的 C# ViewModel classes。
问题:
在 ProjB 中,我在三个单独的文件 中定义了三个 classes,每个都属于它们特定的命名空间 。通过调用例如使用全局构建器配置时builder.UseModules(true, false)
生成的代码不包括引用关键字 extends
之后的类型的转换类型和指定为另一个 class 成员的类型(属于与使用的成员类型不同的另一个命名空间。
例如:
- ProjB.Ns1.Class1
- ProjB.Ns2.Class2
- ProjB.Ns3.Class3
所有三个 classes 只定义了两个简单的道具,其中 Class3 有点不同,包含一个额外的 属性 类型为 Class1。 Class2继承自Class1。
示例代码如下:
// Class1.cs
namespace ReinforcedTypings.DifferentNamespaces.Ns1
{
public class Class1
{
public int AnIntegerPropNs1 { get; set; }
public string AStringPropNs1 { get; set; }
}
}
// Class2.cs
using ReinforcedTypings.DifferentNamespaces.Ns1
namespace ReinforcedTypings.DifferentNamespaces.Ns2
{
public class Class2 : Class1
{
public int AnIntegerPropNs2 { get; set; }
public string AStringPropNs2 { get; set; }
}
}
// Class3.cs
using ReinforcedTypings.DifferentNamespaces.Ns1
namespace ReinforcedTypings.DifferentNamespaces.Ns3
{
public class Class3
{
public int AnIntegerPropNs3 { get; set; }
public string AStringPropNs3 { get; set; }
public Class1 AClass1PropNs3 { get; set; }
}
}
configure方法很简单,定义如下:
public static class RTConfig
{
public static void Configure(ConfigurationBuilder builder)
{
var types = typeof(ReinforcedTypings.DifferentNamespaces.Ns1.Class1).Assembly.GetTypes().ToList();
builder.ExportAsClasses(types.Where(x => x.IsClass), c => c.WithAllFields().WithAllMethods().WithAllProperties());
builder.Global(c => c.UseModules(true, false));
// ^ commenting out this line will also cause a different error
}
}
我使用 .xml 配置文件通过将以下选项 (false) 设置为:
来指定翻译应全部生成一个文件<RtDivideTypesAmongFiles>false</RtDivideTypesAmongFiles>
...这会导致以下 TypeScript 代码(translated.ts 在 .xml 配置文件中设置):
export namespace ReinforcedTypings.DifferentNamespaces.Ns3 {
export class Class3
{
public AnIntegerPropNs3: number;
public AStringPropNs3: string;
public AClass1PropNs3: Class1; // <- error here
}
}
export namespace ReinforcedTypings.DifferentNamespaces.Ns2 {
export class Class2 extends Class1 // <- error here
{
public AnIntegerPropNs2: number;
public AStringPropNs2: string;
}
}
export namespace ReinforcedTypings.DifferentNamespaces.Ns1 {
export class Class1
{
public AnIntegerPropNs1: number;
public AStringPropNs1: string;
}
}
请注意,Class1
类型在扩展后以及 Class3
的已翻译 属性 成员 private AClass1PropNs3: Class1;
中缺少其名称的完整命名空间符号。
这会导致 TypeScript 出现问题,因为由于未指定类型的完整(命名空间)路径名而找不到这些类型。
观察到的附带问题:
当不使用 UseModules 时,如果您注释掉该行,则会在翻译的 TypeScript 代码中发现另一个问题,这是由于翻译代码的顺序,即找不到 Class1
在 Class3
中,因为它在声明之前使用。
结论:
我没有深入研究 RT 的源代码,但我怀疑 UseModules(true, false)
存在一个问题,其中第二个参数明确声明不丢弃命名空间,另一个问题是关于获取的代码的顺序输出。无论如何,将第二个参数值设置为 false 会期望始终随处都有所用类型的 FQN。如果我错误地使用了此配置道具,那么我建议拥有这样的全局配置将对 all/desired 类型强制使用 FQN 大有裨益。
肯定是FQN问题是RT的bug,1.4.6版本已经修复
关于附带问题:参见this GitHub Discussion