Bestaande C#-klassedefinities hergebruiken in TypeScript-projecten

Ik ga gewoon TypeScriptgaan gebruiken in mijn HTML-clientproject dat bij een MVC-project hoort met een entiteitsframework-domeinmodel dat er al is. Ik wil dat mijn twee projecten (clientzijde en serverzijde) volledig gescheiden zijn, aangezien twee teams hieraan zullen werken… JSON en REST worden gebruikt om objecten heen en weer te communiceren.

Natuurlijk moeten mijn domain-objecten aan de clientzijde overeenkomen met de objecten aan de serverzijde. In het verleden deed ik dit normaal gesproken handmatig. Is er een manier om mijn C#-klassedefinities (met name van de POJO-klassen in mijn domeinmodel) opnieuw te gebruiken om de overeenkomstige klassen in TypeScript te maken?


Antwoord 1, autoriteit 100%

Er is momenteel niets dat C# aan TypeScript kan toewijzen. Als je veel POCO’s hebt of denkt dat ze vaak veranderen, kun je een converter maken – iets simpels in de trant van…

public class MyPoco {
    public string Name { get; set; }
}

Naar

export class MyPoco {
    public Name: string;
}

Er is ook een discussie over Codeplex over automatisch genereren vanuit C#.

Om alles up-to-date te houden, kan TypeLite TypeScript-interfaces genereren vanuit C#:

http://type.litesolutions.net/


Antwoord 2, autoriteit 68%

Web Essentialsmaakt het mogelijk om C#-bestanden te compileren naar TypeScript .d.tsbestanden op opslaan. Dan zou je kunnen verwijzen naar de definities van je .ts-bestanden.


Antwoord 3, autoriteit 49%

Als je vscode gebruikt, kun je mijn extensie csharp2tsgebruiken die precies dat doet .

Je selecteert gewoon de geplakte C#-code en voert de opdracht Convert C# to TypeScriptuit vanuit het opdrachtenpalet

Een conversievoorbeeld:

public class Person
{
    /// <summary>
    /// Primary key
    /// </summary>
    public int Id { get; set; }
    /// <summary>
    /// Person name
    /// </summary>
    public string Name { get; set; }
}

naar

export interface Person
{
    /**Primary key */
    Id : number;
    /**Person name */
    Name : string;
}

Antwoord 4, autoriteit 47%

TypeLite en T4TS’s hierboven zagen er allebei goed uit, ik heb er net een gekozen, TypeLite, gevorkt om ondersteuning te krijgen voor

  • Waardetypen,
  • Nullables
  • camelCasing(TypeScript root doc gebruikt kamelen, en dit gaat te mooi samen met C#)
  • openbare velden(houd van schone en leesbare POCO’s, maakt het ook gemakkelijk voor de C#-compiler)
  • modulegeneratie uitschakelen

Toen had ik C# interfacesnodig en dacht dat het tijd was om mijn eigen ding te bakken en schreef een eenvoudig T4-script dat precies doet wat ik nodig heb. Het bevat ook Enums. Geen repo vereist, alleen < 100 regels T4.

Gebruik
Geen bibliotheek, geen NuGet, alleen dit eenvoudige T4-bestand – gebruik “item toevoegen” in Visual Studio en kies een T4-sjabloon. Plak deze dan in het bestand. Pas elke regel met “ACME” erin aan. Voeg voor elke C#-klasse een regel toe

<#= Interface<Acme.Duck>() #>

Bestel telt, elk bekend type zal worden gebruikt in volgenden interfaces. Als je alleen interfaces gebruikt, kan de bestandsextensie zijn .d.ts , voor opsommingen u een Ts file, omdat een variabele is een instantie.

nodig

Aanpassen
Hack het script.

<#@ template debug="true" hostSpecific="true" language="C#" #>
<#@ output extension=".ts" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ assembly name="$(TargetDir)ACME.Core.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Linq" #>
<#= Interface<Acme.Bunny>() #>
<#= Interface<Acme.Duck>() #>
<#= Interface<Acme.Birdy>() #>
<#= Enums<Acme.CarrotGrade>() #>
<#= Interface<Acme.LinkParticle>() #>
<#+  
    List<Type> knownTypes = new List<Type>();
    string Interface<T>()
    {   
        Type t = typeof(T);     
        var sb = new StringBuilder();
        sb.AppendFormat("interface {0} {{\n", t.Name);
        foreach (var mi in GetInterfaceMembers(t))
        {
            sb.AppendFormat("  {0}: {1};\n", this.ToCamelCase(mi.Name), GetTypeName(mi));
        }
        sb.AppendLine("}");
        knownTypes.Add(t);
        return sb.ToString();
    }
    IEnumerable<MemberInfo> GetInterfaceMembers(Type type)
    {
        return type.GetMembers(BindingFlags.Public | BindingFlags.Instance)
            .Where(mi => mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property);
    }
    string ToCamelCase(string s)
    {
        if (string.IsNullOrEmpty(s)) return s;
        if (s.Length < 2) return s.ToLowerInvariant();
        return char.ToLowerInvariant(s[0]) + s.Substring(1);
    }
    string GetTypeName(MemberInfo mi)
    {
        Type t = (mi is PropertyInfo) ? ((PropertyInfo)mi).PropertyType : ((FieldInfo)mi).FieldType;
        return this.GetTypeName(t);
    }
    string GetTypeName(Type t)
    {
        if(t.IsPrimitive)
        {
            if (t == typeof(bool)) return "bool";
            if (t == typeof(char)) return "string";
            return "number";
        }
        if (t == typeof(decimal)) return "number";            
        if (t == typeof(string)) return "string";
        if (t.IsArray)
        {            
            var at = t.GetElementType();
            return this.GetTypeName(at) + "[]";
        }
        if(typeof (System.Collections.IEnumerable).IsAssignableFrom(t)) 
        {
            var collectionType = t.GetGenericArguments()[0]; // all my enumerables are typed, so there is a generic argument
            return GetTypeName(collectionType) + "[]";
        }            
        if (Nullable.GetUnderlyingType(t) != null)
        {
            return this.GetTypeName(Nullable.GetUnderlyingType(t));
        }
        if(t.IsEnum) return "number";
        if(knownTypes.Contains(t)) return t.Name;
        return "any";
    }
    string Enums<T>() // Enums<>, since Enum<> is not allowed.
    {
        Type t = typeof(T);        
        var sb = new StringBuilder();        
        int[] values = (int[])Enum.GetValues(t);
        sb.AppendLine("var " + t.Name + " = {");
        foreach(var val in values) 
        {
            var name = Enum.GetName(typeof(T), val);
            sb.AppendFormat("{0}: {1},\n", name, val);
        }
        sb.AppendLine("}");
        return sb.ToString();
    }
#>

Het volgende niveau van het script zal zijn om de service-interface van de MVC JsonController klasse te maken.


Antwoord 5, gezag 33%

Hier is mijn benadering van het oplossen ervan. Verklaar uw C # klassen met een attribuut en .d.ts-bestanden worden gegenereerd (met behulp van T4-transformaties). Er is een pakket Nuget en de bron is beschikbaar GitHub . Ik ben nog steeds aan het project, maar de steun is vrij uitgebreid.


Antwoord 6, autoriteit 33%

Als u Visual Studio gebruikt, voegt u de Typewriter-extensie toe.

Visual Studio-galerij

Website/Documentatie

Bijwerken

Met Web Essentialsgeïnstalleerd in VS 2015, kunt u met de rechtermuisknop op het klassenbestand klikken en vervolgens > Webbenodigdheden > Maak Typescript Intellisense-bestand vanuit het contextmenu.


Antwoord 7, autoriteit 30%

Probeer het Reinforced.Typings-framework. Het lijkt erop dat het je probleem oplost.

  1. Installeer het vanaf NuGet
  2. Navigeer naar uw POCO en voeg het kenmerk [TsInterface]erboven toe

    using Reinforced.Typings.Attributes;
    namespace YourNamespace {
        [TsInterface]
        public class YourPoco
        {
            public int YourNumber { get;set; }
            public string YourString { get;set; }
            public List<string> YourArray { get;set; }
            public Dictionary<int, object> YourDictionary { get;set; }
        }
    }
    
  3. Je project opnieuw opbouwen
  4. Ontdek de gegenereerde TypeScript-code in het bestand %Your_Project_Directory%/Scripts/project.tsen voeg deze handmatig toe aan het project

    module YourNamespace {
        export interface IYourPoco
        {
            YourNumber: number;
            YourString: string;
            YourArray: string[];
            YourDictionary: { [key: int]: any };
        }
    }
    
  5. Doe hetzelfde voor al je POCO’s en verwijs naar project.tsin je andere TypeScript-code.

Bekijk meer details in documentatiewiki


Antwoord 8, autoriteit 18%

Ik heb een klein hulpprogramma gemaakt dat TypeScript-interfaces kan genereren uit C#-klassen. Is beschikbaar als een NuGet-pakket. Gedetailleerde documentatie is te vinden op de webpagina van het project.


Antwoord 9, autoriteit 16%

Bekijk deze bibliotheek Typewriter

Het converteert niet alleen klassen, opsommingen, interfaces enz., maar ook de api-controllers, wat gewoon geweldig is..

Bovendien doet het dit zodra u het .cs-bronbestand opslaat, zodat ik geen externe tool hoef te activeren. Sla .cs op en u krijgt bijgewerkte .ts


Antwoord 10, autoriteit 11%

Ik heb een kleine oplossing die T4-sjablonen gebruikt (bron weergeven).

Je gaat van elke CLR POCO:

public class Parent : Person
{
    public string Name { get; set; }
    public bool? IsGoodParent { get; set; }
    public virtual ICollection<Child> Children { get; set; }
}

Naar een TypeScript-interface:

///<reference path="Child.d.ts" />
///<reference path="Person.d.ts" />
interface Parent extends Person {
    Name : string;
    IsGoodParent? : bool;
    Children : Child[];
}

Antwoord 11, autoriteit 5%

U kunt het open-sourceproject NSwaggebruiken: in de GUI kunt u .NET-klasse selecteren uit een bestaande . NET DLL en genereer de TypeScript-interface ervoor.

Het project biedt ook opdrachtregeltools en ondersteuning voor T4-sjablonen, evenals het genereren van clientcode voor Web API-controllers…


Antwoord 12, autoriteit 5%

Je kunt dit ook gebruiken: https://github.com/pankleks/TypeScriptBuilder

Deze kleine bibliotheek genereert TypeScript-typedefinitie op basis van C#-types.
Gebruik het rechtstreeks in uw backend C#-project om code te genereren voor uw frontend TypeScript-project.
Je kunt ook een kleine console-app schrijven om code te genereren door vooraf gemaakte tools.

Werkt op Full & NET Core-framework!

Installeren via nuget:
Install-Package TypeScriptBuilder

Ondersteunde functies

  • Type-afhankelijkheid oplossen
  • Algemeen
  • Type overerving
  • Naamruimten (modules)
  • Opsommingen
  • Nullable-typen
  • Woordenboekconversie (naar sterk type TS geïndexeerde objecten)
  • Set van controleattributen voor codegeneratie
  • anyvoor typen die niet kunnen worden geconverteerd

Meer beschrijving: https://github.com/pankleks/TypeScriptBuilder/blob /master/README.md


Antwoord 13, autoriteit 5%

Als u een apart bestand moet maken voor elke gegenereerde TypeScript-klasse/interface (dwz op een “enkele klasse per bestand”-manier), kunt u TypeGen. Het is een tool die u vanuit de Package Manager Console kunt gebruiken om TypeScript-bestanden te genereren op basis van uw C#-klassen/enums. Het ondersteunt momenteel:

  • exporteren van opsommingen; POCO’s exporteren als TS-klassen of interfaces
  • erfenis
  • algemene typen
  • verzameling / geneste verzamelingstypen

plus enkele extra functies. Het is ook open source (je kunt het bekijken op github).


Antwoord 14, autoriteit 4%

Hoe zit het andersom?

Bekijk erecruit TypeScript Translator. Het wordt geleverd met kant-en-klare C#-ondersteuning, maar is eigenlijk op sjablonen gebaseerd (gebruikt Nunjucks voor weergave), wat betekent dat het al het andere kan genereren – VB.NET, F#, C++, XML, SQL – wat je ook maar kunt coderen met een sjabloon.

Werkt als een .NET-consoleprogramma, NodeJS-programma (voor degenen die niet op Windows werken), of als een Visual Studio-extensie, compleet met functionaliteit voor genereren bij opslaan. En bevat MSBuild-ondersteuning, gewoon om je build-server blij te maken. 🙂


Antwoord 15, autoriteit 4%

Jongens kijk eens op https://github.com/reinforced/Reinforced.Typings . Ik heb de afgelopen dagen met typelite- en t4-sjablonen gespeeld en ben bij dit project uitgekomen. Het is supereenvoudig en werkt als een tierelier. Pak gewoon het pakket, wijzig het configuratiebestand (het duurt ongeveer 10 seconden) en bouw het op. Alles wordt automatisch gedaan zonder problemen. Zegen de auteur!

Het slechte van T4-sjablonen is dat als je eenmaal vanuit VS bouwt, de gescande assemblages worden vergrendeld en je VS opnieuw moet opstarten (hoe gek is dat?). Er is een tijdelijke oplossing in T4 Toolbox + enkele VS-opschoningsrichtlijnen, maar geen van deze werkte voor mij.


Antwoord 16, autoriteit 2%

Ik hou van de citykid-oplossing. Ik had het een beetje verlengd.
De oplossing is dus ook gebaseerd op codegeneratietechniek met T4-sjablonen.

Het kan veelvoorkomende TypeScript-typen en ambient-declaraties genereren.

Het ondersteunt overerving en interface-implementaties.

Ondersteunt generieke termen, arrays en lijsten als typevelden.

Het vertaalt zich ook naar TypeScript-typen die niet expliciet in de configuratie worden genoemd (we importeren bijvoorbeeld type A, en in TS-uitvoer kun je enkele andere typen vinden: typen van de velden, basistypen en interfaces).

Je kunt ook de naam van het type overschrijven.

Enums worden ook ondersteund.

Gebruiksvoorbeeld (u kunt het vinden in de projectrepository):

// set extension of the generated TS file
<#@ output extension=".d.ts" #>
// choose the type of TS import TsMode.Ambient || TsMode.Class
<# var tsBuilder = new TsBuilder(TsMode.Ambient); #>
// reference assembly with the c# types to be transformed
<#@ assembly name="$(SolutionDir)artifacts\...\CsT4Ts.Tests.dll" #>
// reference namespaces
<#@ import namespace="CsT4Ts.Tests" #>
<#
    //add types to processing
    tsBuilder.ConsiderType(typeof(PresetDTOBase), "PresetBase");
    tsBuilder.ConsiderType(typeof(PresetDTO), "Preset");
    tsBuilder.ConsiderType(typeof(TestInterface<,>));
#>
// include file with transformation algorithms
<#@ include file="CsT4Ts.t4" #>

En je krijgt een output

//CsT4Ts.Tests.PresetDTOBase => PresetBase
// CsT4Ts.Tests.PresetDTO => Preset
// CsT4Ts.Tests.TestInterface`2 => TestInterface
// CsT4Ts.Tests.TestEnum => TestEnum
declare class PresetBase
{
    PresetId: string;
    Title: string;
    InterviewDate: string;
}
declare class Preset extends PresetBase
{
    QuestionsIds: string[];
}
declare interface TestInterface<TA, TB>
{
    A: string;
    B: number;
    C: TestEnum;
    D: TestEnum[];
    E: number[];
    F: TA;
    G: TB[];
}
declare enum TestEnum
{
    Foo = 10,
    Boo = 100
}

Bekijk hier de volledige oplossing: https://bitbucket.org/chandrush/cst4ts


Antwoord 17, autoriteit 2%

U kunt ook Bridge.net gebruiken. Vanaf versie 1.7 ondersteunt het het genereren van TypeScript
definities voor C#-typen. Zie http://bridge.net/docs/generate-typescript-definitions/


Antwoord 18, autoriteit 2%

Ik vond het antwoord van @citykid ook erg leuk, dus ik heb het uitgebreid om een ​​hele naamruimte tegelijk te gebruiken. Plaats gewoon de POCO-klassen in de naamruimte en bouw T4-sjablonen opnieuw op. Ik wou dat ik wist hoe ik voor elk afzonderlijke bestanden kon genereren, maar dat is niet het einde van de wereld.

Je moet verwijzen naar de .DLL-bestanden in het bovenste gedeelte (waar de klassen zijn die je wilt) en je moet de naamruimten vermelden. Alle te bewerken regels zijn gemarkeerd met ACME. Grote complimenten voor @citykid, waardeer het!

<#@ template debug="true" hostSpecific="true" language="C#" #>
<#@ output extension=".ts" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ assembly name="$(TargetDir)YOUR_DLL_NAME_HERE_ACME.dll" #>
<#@ assembly name="$(TargetDir)YOUR_OTHER_DLL_NAME_HERE_ACME.dll" #>
<#@ assembly name="$(TargetDir)YOUR_OTHER_DLL_NAME_HERE_ACME.dll" #>
<#@ assembly name="$(TargetDir)YOUR_OTHER_DLL_NAME_HERE_ACME.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Reflection" #>
<#= Process("My.Very.Special.Namespace.ACME") #>
<#= Process("My.Other.Very.Special.Namespace.ACME") #>
<#= Process("My.Other.Very.Special.Namespace.ACME") #>
<#= Process("My.Other.Very.Special.Namespace.ACME") #>
<#+  
    List<Type> knownTypes = new List<Type>();
    string Process(string nameSpace) {
      var allass = AppDomain.CurrentDomain.GetAssemblies();
      var ss = "";
      foreach (var ass in allass)
      {
         ss += ProcessAssembly(ass, nameSpace);
      }
      return ss;
    }
   string ProcessAssembly(Assembly asm, string nameSpace) {
      try {
            Type[] types;
            try
            {
                types = asm.GetTypes();
            }
            catch (ReflectionTypeLoadException e)
            {
                types = e.Types;
            }
            var s = "";
            foreach (var t in types.Where(t => t != null))
            {
               try {
               if (String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal))
               {
                    s += InterfaceOfType(t);
               }
               } catch (Exception e)
               {
               }
            }
            return s;      
      }
      catch (Exception ee2) {
        return "// ERROR LOADING TYPES: " + ee2;
      }
   }
    string InterfaceOfType(Type T)
    {   
        Type t = T;     
        var sb = new StringBuilder();
        sb.AppendFormat("interface {0} {{\r\n", t.Name);
        foreach (var mi in GetInterfaceMembers(t))
        {
            sb.AppendFormat("  {0}: {1};\r\n", this.ToCamelCase(mi.Name), GetTypeName(mi));
        }
        sb.AppendLine("}");
        knownTypes.Add(t);
        return sb.ToString();
    }
    string Interface<T>()
    {   
        Type t = typeof(T);     
        var sb = new StringBuilder();
        sb.AppendFormat("interface {0} {{\n", t.Name);
        foreach (var mi in GetInterfaceMembers(t))
        {
            sb.AppendFormat("  {0}: {1};\r\n", this.ToCamelCase(mi.Name), GetTypeName(mi));
        }
        sb.AppendLine("}");
        knownTypes.Add(t);
        return sb.ToString();
    }
    IEnumerable<MemberInfo> GetInterfaceMembers(Type type)
    {
        return type.GetMembers(BindingFlags.Public | BindingFlags.Instance)
            .Where(mi => mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property);
    }
    string ToCamelCase(string s)
    {
        if (string.IsNullOrEmpty(s)) return s;
        if (s.Length < 2) return s.ToLowerInvariant();
        return char.ToLowerInvariant(s[0]) + s.Substring(1);
    }
    string GetTypeName(MemberInfo mi)
    {
        Type t = (mi is PropertyInfo) ? ((PropertyInfo)mi).PropertyType : ((FieldInfo)mi).FieldType;
        return this.GetTypeName(t);
    }
    string GetTypeName(Type t)
    {
        if(t.IsPrimitive)
        {
            if (t == typeof(bool)) return "boolean";
            if (t == typeof(char)) return "string";
            return "number";
        }
        if (t == typeof(decimal)) return "number";            
        if (t == typeof(string)) return "string";
        if (t.IsArray)
        {            
            var at = t.GetElementType();
            return this.GetTypeName(at) + "[]";
        }
        if(typeof (System.Collections.IEnumerable).IsAssignableFrom(t)) 
        {
            var collectionType = t.GetGenericArguments()[0]; // all my enumerables are typed, so there is a generic argument
            return GetTypeName(collectionType) + "[]";
        }            
        if (Nullable.GetUnderlyingType(t) != null)
        {
            return this.GetTypeName(Nullable.GetUnderlyingType(t));
        }
        if(t.IsEnum) return "number";
        if(knownTypes.Contains(t)) return t.Name;
        return "any";
    }
    string Enums<T>() // Enums<>, since Enum<> is not allowed.
    {
        Type t = typeof(T);        
        var sb = new StringBuilder();        
        int[] values = (int[])Enum.GetValues(t);
        sb.AppendLine("var " + t.Name + " = {");
        foreach(var val in values) 
        {
            var name = Enum.GetName(typeof(T), val);
            sb.AppendFormat("{0}: {1},\r\n", name, val);
        }
        sb.AppendLine("}");
        return sb.ToString();
    }
#>

Antwoord 19

Mijn oplossing was om een ​​kleine codegen-util te schrijven die eenvoudigweg een project-assembly (en verwijzende assemblies) nodig heeft en beginnen met het scannen van typen die betrokken zijn bij de interactie tussen typoscript en c#. Deze util voert zowel javascript als d.ts uit …
De tool wordt genoemd in het post-build event … werkt als een tierelier!


Antwoord 20

Als je geïnteresseerd bent, kun je TypedRpcgebruiken. Het doel is niet alleen om de interfaces in TypeScript te maken, maar om alle communicatie met de service in .Net tot stand te brengen met behulp van het JsonRpc-protocol.

Voorbeeld voor een klas in server:

[TypedRpc.TypedRpcHandler]
public class RpcServerExample
{
    public String HelloWorld()
    {
        return "Hello World!";
    }
}

Gebruik van gegenereerde TypeScript-code:

/// <reference path="Scripts/TypedRpc.ts" />
let rpc: TypedRpc.RpcServerExample = new TypedRpc.RpcServerExample();
var callback = function(data, jsonResponse) {
    console.log(data);
};
rpc.HelloWorld().done(callback).fail(callback);

Bekijk https://github.com/Rodris/TypedRpcvoor andere voorbeelden van gebruik het.


Antwoord 21

ASP.NET Web API Client Generatorskunnen handiger zijn, minder overhead dan swagger toolchain en andere tijdens SDLC.

Terwijl programmeurs over het algemeen WebApiClientGen gebruiken om client-API-codes te genereren, biedt dit project ook POCO2TS.exe, een opdrachtregelprogramma dat TypsScript-interfaces genereert uit POCO-klassen. U kunt Poco2ts.exe of de poco2ts-component gebruiken om de codegeneratie te integreren met uw build-pipeline.


Antwoord 22

Als u het via node.js wilt converteren, kunt u dit pakket gebruiken (csharp-to-typescript).
https://www.npmjs.com/package/csharp-to-typescript

sourcode: https://github.com/YuvrajSagarRana/csharp-to-typescript

eg: 
// After installation, import the package.
var { CsharpToTs, getConfiguration } = require("csharp-to-typescript");
// Use CsharpToTs to convert your source code a. Method one give your source code as string:
const sourceCodeInString =   `public class Address
{
  public int Id {get; set;}
  public string Street { get; set; }
  public string City { get; set; }
}`
var outputTypescript = CsharpToTs(sourceCodeInString, getConfiguration());
console.log(outputTypescript);
// Output is
export class Address
{
  Id: number;
  Street: string;
  City: string;
}

Antwoord 23

Als je VSCode gebruikt, kun je die extensie bekijken C# naar TypeScript

Bekijk hoe ik het met één klik van C#-code kan converteren. Natuurlijk zullen niet alle klassen worden omgebouwd zoals de fabriek, maar voor de klant is het goed genoeg. We hebben alleen de vorm van gegevens nodig. Soms, als ik het bezoekerspatroon moet gebruiken, zal ik decoreren met extra methoden die ik nodig heb. Het duurde slechts 5 seconden om dit te doen. In vergelijking met één minuut hierboven, zou ik kunnen zeggen dat het een grote overwinning is.

Bekijk meer details in mijn blogbericht


Antwoord 24

Ik heb hierover een functieverzoek geschreven op de Developer Community-pagina:

https://developercommunity .visualstudio.com/idea/1153873/reuse-existing-net-classes-for-typescript-definiti.html

Zoals je in de antwoorden hier kunt zien, zijn er veel projecten die dit proberen op te lossen, maar helaas zijn veel van deze projecten projecten met één ontwikkelaar die onderweg niet meer worden ondersteund. Ik denk dat het heel netjes zou zijn als Microsoft in plaats daarvan een van deze projecten zou onderhouden, door een .NETnaar TypeScriptgenerator te maken.

Sommige worden onder andere nog steeds onderhouden, maar zijn sterk afhankelijk van één enkele ontwikkelaar:

TypeLite:

https://bitbucket.org/LukasKabrt/typelite/src/default/

TypeScript-definitiegenerator:

https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TypeScriptDefinitionGenerator

Typewriter:

https://github.com/frhagn/typewriter

Typegen:

https://github.com/jburzynski/typegen

versterkte.Typings:

https://github.com/reinforced/reinforced.typings

Mijn tip zou zijn om een ​​project te kiezen dat u vanaf het begin kunt stoppen om te stoppen met behouden en bereid is om over te schakelen naar iets dat momenteel wordt gehandhaafd. Ik zou gaan voor iets dat annotaties gebruikt en mijn vingers kruisen, ik kan simpelweg die tag vervangen door iets anders als dat project stopt met ondersteund worden.


Antwoord 25

Ik gebruik een kleine aangepaste DSL die zowel typoscopen als C # DTO / POCO-klassen genereert. De DSL ziet eruit als het volgende:

output CSharp
output TypeScript
namespace MyLibrary.Logic.DataModel.DTOs
class Something
property int ID
property string Name
property DateTime DateTime
property int ForeignKeyID

Op deze manier heb ik een DTO-model met een enkele bron (de DSL) en zit tussen de twee C # en Typcript Logic-modellen.

Ik schrijf vervolgens zowel een C # en typescript Dtofactory-klasse met methoden die verantwoordelijk zijn voor het converteren tussen DTO’s en logische modelobjecten. (En een deel van de DTO-generatie zijn serialisatiemethoden die converteren naar een anoniem JSON-geschikt type voor serialisatie of voor het opslaan in indexeddb.)

Door dit te doen, zodra er aan beide kanten een model verandert, krijg ik compilatiefouten totdat beide partijen weer overeenkomen.

Other episodes