reinforced / Reinforced.Typings

Converts C# classes to TypeScript interfaces (and many more) within project build. 0-dependency, minimal, gluten-free

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Create an anonymous type programmatically

ReinisV opened this issue · comments

I want to build an RtArgument whose type is anonymous object whose shape is decided at runtime.

The C# code should be something like:

    internal class BuildResultCodeGenerator : ClassCodeGenerator
    {
        public override RtClass GenerateNode(Type element, RtClass result, TypeResolver resolver)
        {
            // First of all, we fetch original AST node that is being generated by default
            result = base.GenerateNode(element, result, resolver);
            if (result == null) return null;

            var constructor = new RtConstructor
            {
                Arguments = new List<RtArgument>
                {
                    new()
                    {
                        Type = new RtAnonymousObjectType
                        {
                            Members = new Dictionary<RtIdentifier, RtTypeName>
                            {
                                {new RtIdentifier("stringField"), resolver.ResolveTypeName(typeof(String))},
                                {new RtIdentifier("numberField"), resolver.ResolveTypeName(typeof(Int32))},
                            }
                        },
                        Identifier = new RtIdentifier("something")
                    }
                },
                Body = new RtRaw(""),
            };
            result.Members.Add(constructor);
        }
    }

    public sealed class RtAnonymousObjectType : RtTypeName
    {
        /// <summary>Type for dictionary key</summary>
        public Dictionary<RtIdentifier, RtTypeName> Members { get; set; }

        /// <inheritdoc />
        public override IEnumerable<RtNode> Children
        {
            get
            {
                foreach (var identifierTypePair in this.Members.ToList())
                {
                    yield return (RtNode)identifierTypePair.Value;
                }
            }
        }

        /// <inheritdoc />
        public override void Accept(IRtVisitor visitor) => visitor.Visit(this);

        /// <inheritdoc />
        public override void Accept<T>(IRtVisitor<T> visitor) => visitor.Visit(this);

        /// <inheritdoc />
        public override string ToString() => $"{{ {String.Join(",\n", this.Members.ToList().Select(identifierTypePair => $"{identifierTypePair.Key}: {identifierTypePair.Value}"))} }}";
    }

The result should be something like:

export class BuildResult
{
	constructor (something: {stringField: string, numberField: number}) { } 
}

Obviously, this C# code doesnt work, I get an "unknown node passed" error from here, but I can't find any Rt structures that would work. The closest seems to be RtDictionaryType, but that does not allow to set specific field names.

What am I missing?