Overview:
Within my solution, I have two projects: ProjA and ProjB. In ProjA, I've defined a custom RTConfigure
method to streamline the configuration process for translating C# to TypeScript using the Reinforced.Typings tool. Meanwhile, ProjB houses C# ViewModel classes that are meant for translation.
Issue at Hand:
While working in ProjB, I encountered an issue with three classes residing in separate files, each belonging to its unique namespace. When utilizing a global builder configuration through builder.UseModules(true, false)
, the resulting code fails to include fully qualified namespace names for types referenced after the extends
keyword or when specified as members of a different class (belonging to a distinct namespace from the used member's type).
Illustrative Example:
- ProjB.Ns1.Class1
- ProjB.Ns2.Class2
- ProjB.Ns3.Class3
All three classes feature just two basic properties, with Class3 slightly differing by having an additional property of the type Class1. Furthermore, Class2 inherits from Class1.
Sample Code Snippets:
// 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; }
}
}
The config method is straightforward and defined as follows:
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
}
}
I utilize the .xml configuration file to specify that all translations should be consolidated into one file by setting the following option (false) like so:
<RtDivideTypesAmongFiles>false</RtDivideTypesAmongFiles>
This results in the ensuing TypeScript code (saved in translated.ts as configured in the .xml file):
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;
}
}
It's noteworthy that Class1
lacks the full namespace designation after extends
, leading to issues locating these types in TypeScript due to the absence of the complete path name.
Addendum Issue Observed:
Should you opt out of utilizing UseModules, and consequently comment out that line, another complication arises within the generated TypeScript code pertained to the order of translation. Specifically, Class1
may not be recognized within Class3
as it is referenced before being declared.
In Conclusion:
Though I haven't delved deep into the source of RT, a potential point of concern lies in the UseModules(true, false)
function where the second argument explicitly denounces discarding namespaces, alongside an issue concerning the sequencing of outputted code. With the second argument set to false, one would anticipate consistent usage of FQN for all desired types. Should there be any misconceptions regarding the utilization of this config parameter, I propose the implementation of a universal configuration that mandates the use of FQN for all/relevant types, which could greatly enhance the workflow.