टाइपस्क्रिप्ट प्रोजेक्ट्स में मौजूदा C # क्लास परिभाषाओं का पुन: उपयोग कैसे करें


121

मैं सिर्फ TypeScriptअपने HTML क्लाइंट प्रोजेक्ट में उपयोग शुरू करने जा रहा हूं जो MVC प्रोजेक्ट से संबंधित है, जिसमें पहले से ही एक इकाई फ्रेमवर्क डोमेन मॉडल है। मैं चाहता हूं कि मेरे दो प्रोजेक्ट (क्लाइंट साइड और सर्वर साइड) पूरी तरह से अलग हो जाएं क्योंकि दो टीमें इस पर काम करेंगी ... JSON और REST का उपयोग ऑब्जेक्ट्स को आगे-पीछे करने के लिए किया जाता है।

बेशक, domainक्लाइंट साइड पर मेरी ऑब्जेक्ट्स को सर्वर साइड पर ऑब्जेक्ट्स से मेल खाना चाहिए। अतीत में, मैंने सामान्य रूप से मैन्युअल रूप से ऐसा किया है। क्या POJOटाइपस्क्रिप्ट में संबंधित कक्षाओं को बनाने के लिए मेरी सी # वर्ग परिभाषाओं (विशेष रूप से मेरे डोमेन मॉडल में कक्षाएं) का पुन: उपयोग करने का एक तरीका है "?


नहीं, वे पूरी तरह से अलग भाषाएं हैं।
हंस पसंत

6
हां मेरा मतलब POCO था। मुझे पता है कि वे पूरी तरह से अलग-अलग भाषाएं हैं ... लेकिन किसी भी तरह से यह सब टाइप करने से बचना बहुत अच्छा होगा ... मुझे लगता है कि फिलहाल मैं अपने सी # कोड को कॉपी और पेस्ट करूंगा .. और जब तक यह संकलित नहीं करता, तब तक इसे कुछ भी रिफैक्ट करेगा। टाइपस्क्रिप्ट ... इस तरह से मुझे यकीन है कि मैंने एक विशेषता गलत नहीं लिखी है .. और मुझे याद नहीं रखने में मदद करें। लेकिन यह स्पष्ट रूप से अच्छा नहीं लगता है।
पाब्लोउस्तोंडो

1
मुझे दूसरी दिशा में भी दिलचस्पी है - टाइपस्क्रिप्ट मॉडल कक्षाओं से लेकर सी # मॉडल कक्षाओं तक, JSON के माध्यम से द्विदिश रूप से वांछनीय।
जेसन क्लेबन

मैं उसी की तलाश कर रहा हूं और मैं अभी इस गल्प प्लगइन पर ठोकर खा चुका हूं, हालांकि मुझे नहीं पता कि इसके लिए कितना समर्थन है
ल्यूक टी ओ ब्रायन

जवाबों:


54

वर्तमान में ऐसा कुछ भी नहीं है जो टाइप # के लिए C टाइप करें। यदि आपके पास बहुत सारे POCO हैं या आपको लगता है कि वे अक्सर बदल सकते हैं, तो आप एक कनवर्टर बना सकते हैं - की तर्ज पर कुछ सरल ...

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

सेवा

export class MyPoco {
    public Name: string;
}

कोडप्लेक्स पर C # से ऑटो-जेनरेट करने के बारे में भी चर्चा है

बस चीजों को अद्यतन रखने के लिए, टाइपलाइट C # से टाइपस्क्रिप्ट इंटरफेस उत्पन्न कर सकता है:

http://type.litesolutions.net/


हाँ, ऐसा कुछ है जो मैं मैन्युअल रूप से करने के लिए सोच रहा था .. अच्छा। यकीन नहीं है कि मेरे पास अभी एक कनवर्टर लिखने का समय है .. लेकिन हां, यह विचार होगा। धन्यवाद। हो सकता है कि Microsoft अभी यह कर रहा है कि अभी हम बोलते हैं।
पाब्लोउस्तोंडो

आप इसे किसी भी दो तरीकों से कर सकते हैं ... EnvDTE ऑटोमेशन की मदद से या। Mef डायरेक्टरी कैटलॉग और रिफ्लेक्शन / इंट्रोस्पेक्शन का उपयोग करके फाइलें उत्पन्न करें। मैं दूसरे को पसंद करता हूं क्योंकि यह दृश्य पर निर्भर नहीं करता है।
अरेक बाल

1
मैं डार्ट का उपयोग करना शुरू कर रहा था और सी # और जावास्क्रिप्ट के बीच प्रकार साझा करने के एक ही मुद्दे में भाग गया। मुझे आशा है कि यह समस्या टाइपस्क्रिप्ट द्वारा हल की जाएगी, लेकिन ऐसा लगता है कि उत्तर अभी तक नहीं है। मैं साल्टेरल-कम्पाइलर से भी थोड़ा खराब हो गया था, जो कि c # को जावास्क्रिप्ट में संकलित करता था, बल्कि अच्छी तरह से नमक के लिए-compiler.com
BraveNewMath

2
@DanielHarvey Enums टाइपलाइट द्वारा सही तरीके से उत्पन्न किए गए हैं, शायद आपकी टिप्पणी के बाद से तय किए गए हैं।
पउलोया

1
TypeScriptPaste C # में प्रवेश करेगा। आपके पास रोज़लिन कंपाइलर होना चाहिए, जिसका अर्थ है विज़ुअल स्टूडियो 2015, लेकिन यह वास्तव में अच्छी तरह से काम करता है। इसकी 100% नहीं है और मुझे कुछ कोड को डंप करना पड़ा - लूप्स के लिए फ़ॉर्वर्ड में कनवर्ट करना, अपनी सूची लिखना <T> वर्ग, उदाहरण के लिए, और आपको कोड बनाना होगा ताकि इसकी 'शुद्ध' केवल आंतरिक डेटा संरचनाओं के साथ हो सके के साथ काम करते हैं, लेकिन वीएस में कोड को संशोधित करने और परीक्षण करने में सक्षम होने के लिए भुगतान करने के लिए यह एक छोटी सी कीमत थी और फिर टाइपस्क्रिप्ट के माध्यम से इसे जावास्क्रिप्ट में 'कंपाइल' किया।
जॉन मोट

36

वेब एसेंशियल्स.d.ts सेव पर टाइपस्क्रिप्ट फ़ाइलों के लिए सी # फाइल संकलित करने की अनुमति देते हैं । तब आप अपनी .tsफ़ाइलों से परिभाषाओं का संदर्भ दे सकते हैं ।

यहां छवि विवरण दर्ज करें


क्या आप शायद .ts फ़ाइलों और c # को भ्रमित कर रहे हैं? इस विकल्प को नहीं पा सकते हैं
Flores

1
लेकिन कुछ खोज के बाद मैंने पाया कि आपका क्या मतलब है .. वास्तव में काफी उपयोगी है।
फ्लोर्स

2
वास्तव में यह नहीं है, मुझे पूरा यकीन है कि ऑपरेशन 'कुछ भी नहीं' संकलित करता है, यह कोड उत्पन्न करता है। यह मुझे उलझन में है, लेकिन 99% सही नहीं है, मैं आपको देता हूँ ;-)
फ़्लोरेस

1
यह अधिक उपयोगी था अगर हम इसके नाम स्थान और कुछ अनुकूलन को कॉन्फ़िगर कर सकते।
फर्षिद सबरी

5
अब आपको इसका उपयोग करने के लिए मैन्युअल रूप से 'टाइपस्क्रिप्ट डेफिनिशन जेनरेटर' इंस्टॉल करना होगा - यहाँ
तरन

24

टाइपलाइट और T4TS दोनों के ऊपर अच्छा लग रहा था, बस एक को टाइप किया, टाइपलाइट ने समर्थन पाने के लिए इसे छोड़ दिया

  • ValueTypes ,
  • Nullables
  • camelCasing (टाइपप्रति जड़ दस्तावेज़ ऊंटों का उपयोग करता है, और इस के साथ सी # बहुत अच्छा एक साथ चला जाता है)
  • सार्वजनिक क्षेत्र (स्वच्छ और पठनीय POCOs प्यार करते हैं, यह C # कंपाइलर के लिए भी आसान बनाता है)
  • मॉड्यूल पीढ़ी को निष्क्रिय करें

तब मुझे C # इंटरफेस की आवश्यकता थी और सोचा कि यह मेरी खुद की चीज़ को सेंकने का समय है और एक साधारण T4 स्क्रिप्ट लिखी है, जो मुझे चाहिए। इसमें एनम भी शामिल है । कोई रेपो की आवश्यकता नहीं है, टी 4 की बस <100 लाइनें।

उपयोग
नहीं पुस्तकालय, कोई NuGet, बस इस सादे सरल T4 फ़ाइल - दृश्य स्टूडियो में "आइटम जोड़ें" का उपयोग करें और किसी भी T4 टेम्पलेट का चयन करें। फिर इसे फाइल में पेस्ट करें। इसमें "ACME" के साथ हर लाइन को एडॉप्ट करें। प्रत्येक C # वर्ग के लिए एक पंक्ति जोड़ें

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

आदेश मामलों, किसी भी ज्ञात प्रकार का उपयोग फ़ॉल्विंग इंटरफेस में किया जाएगा। यदि आप केवल इंटरफेस का उपयोग करते हैं, तो फ़ाइल एक्सटेंशन .d.ts हो सकता है , एन्स के लिए आपको एक .ts फ़ाइल की आवश्यकता होती है , क्योंकि एक चर त्वरित है।

अनुकूलन
स्क्रिप्ट को हैक करें

<#@ 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();
    }
#>

स्क्रिप्ट का अगला स्तर MVC JsonController वर्ग से सेवा इंटरफ़ेस बनाने के लिए होगा।


1
बहुत प्यारा है, लेकिन आप typeof(ParticleKind)में है Enum<T>। निश्चित रूप से वह होना चाहिए typeof(T)? इसके अलावा आपको बाद के टाइपस्क्रिप्ट संस्करणों के लिए अद्यतन boolकरने की आवश्यकता हैboolean
कोडिंग कोडिंग

यह भी ध्यान दें: यह कक्षाओं में एनम गुणों के साथ टूटता है
कोडिंग किया गया

1. उह, हाँ, सिर ऊपर करने के लिए धन्यवाद, इसे ठीक कर देंगे। 2. इस स्क्रिप्ट को लिखने के बाद से टाइपस्क्रिप्ट विकसित हुई। ऐसा लगता है कि इसे कुछ अद्यतन की आवश्यकता हो सकती है, आप निश्चित रूप से सही हैं। मुझे आशा है कि यह आपके अपने उद्देश्य के लिए एक प्रारंभिक बिंदु के रूप में कार्य करेगा।
शहरकी

1
मैंने इसे एक हेल्पर लाइब्रेरी में बदल दिया, बग्स को ठीक कर दिया और अब इंटरफेस और नए const enumएस उत्पन्न करने के लिए मेरी टीटी फाइलों में सिर्फ सिंगल-लाइन प्रविष्टियों का उपयोग करें । उदाहरण के लिए धन्यवाद। यह बहुत करीब था और मुझे बहुत तेजी से काम करने का परिणाम मिला।
कोडिंग हो गई

24

यदि आप vscode का उपयोग करते हैं तो आप मेरे एक्सटेंशन csharp2ts का उपयोग कर सकते हैं जो वास्तव में ऐसा करता है।

आप बस पेस्ट किए गए C # कोड का चयन करें और Convert C# to TypeScriptकमांड पैलेट से कमांड चलाएं यहां छवि विवरण दर्ज करें एक रूपांतरण उदाहरण:

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

    /// <summary>
    /// Person name
    /// </summary>
    public string Name { get; set; }
}

सेवा

export interface Person
{
    /**Primary key */
    Id : number;

    /**Person name */
    Name : string;
}

1
मुझे लगता है कि लोग पूरी तरह से स्वचालित समाधान में रुचि रखते हैं जहां msbuild के साथ संकलित करने से पहले उन्हें टाइप करने वाली परिभाषाओं का आउटपुट मिलता है। वहाँ एक तरीका है कि प्लगइन का उपयोग कर रहा है?
बिंकी

नहीं, यह एक VSCode प्लगइन, केवल संपादक के अंदर ही काम करता है न कि एक अकेले खड़े कार्यक्रम के रूप में
राफेल

यदि आप नोड.जेएस या टाइटलस्क्रिप्ट के माध्यम से चाहते हैं तो मैंने इस vscode एक्सटेंशन को नोड मॉड्यूल में बदल दिया है। आप यहाँ रेपो की जाँच कर सकते हैं: github.com/YuvrajSagarRana/csharp-to-typescript
सागर राणा मगर

क्या कमांड को कीबोर्ड शॉर्टकट से लिंक करने का कोई तरीका है? उदाहरण के लिए, .net कोड का चयन करेगा, और "Shift C # को टाइपस्क्रिप्ट में कनवर्ट" करने के लिए सेटअप शिफ्ट + ctrl + c होगा, जो प्रक्रिया को गति देगा। मुझे प्लगइन पसंद है!
पावेल कियोच

18

यहाँ इसे हल करने के लिए मेरा दृष्टिकोण है। अपनी C # कक्षाओं को एक विशेषता के साथ घोषित करें और .d.ts-files (T4 ट्रांसफ़ॉर्म का उपयोग करके) उत्पन्न की जाएंगी। नगेट पर एक पैकेज है और जीथब पर स्रोत उपलब्ध है । मैं अभी भी परियोजना पर काम कर रहा हूं, लेकिन समर्थन बहुत व्यापक है।


मैंने इस प्रोजेक्ट को
कांटेक्ट किया

18

यदि आप Visual Studio का उपयोग कर रहे हैं, तो टाइपराइटर एक्सटेंशन जोड़ें।

विजुअल स्टूडियो गैलरी

वेबसाइट / प्रलेखन

अपडेट करें

वीएस 2015 में स्थापित वेब एसेंशियल के साथ , आप क्लास फाइल को राइट-क्लिक कर सकते हैं, फिर> वेब एसेन्सेस> संदर्भ मेनू से टाइपस्क्रिप्ट इन्टेलिसेन्स फाइल बनाएं।


इसने intellisense के समर्थन के लिए d.ts फ़ाइल बनाई लेकिन कोई इसका उपयोग कैसे करता है और फिर अंतर्निहित कक्षाएं बनाने के साथ क्या संबंध है? मैं WebEssentails पर गया और कोई डॉक्स नहीं खोज सका। कोई सुझाव? TIA।
हॉवर्डलो

@ जियो जो भी .ts फ़ाइल को केवल .ts फ़ाइल में संदर्भित करता है। u फ़ाइल को इसमें उपयोग करने की आवश्यकता होती है। जब आप अपनी कक्षा बदलते हैं, तो अंतर्निहित d.ts फ़ाइल अपडेट हो जाएगी। (टिप: आप d.ts को ड्रैग और ड्रॉप कर सकते हैं। .ts फ़ाइल के शीर्ष पर फ़ाइल करें और यह आपके लिए संदर्भ बनाएगा।)
माइकल ट्रेंचिडा

धन्यवाद माइकल! मैंने d .ts फ़ाइल को एक खाली .ts फ़ाइल में छोड़ने का प्रयास किया और इसने केवल फ़ाइल को फ़ोल्डर में जोड़ा। इसे VS2015 और नए VS2017 में आज़माया, वही परिणाम। क्या आप किसी ऐसे वीडियो या ट्यूटोरियल के बारे में जानते हैं जो दिखाता है कि यह सब कैसे काम करता है? टीआईए
हावर्डो

मैंने संपादक में d .ts फ़ाइल को .ts फ़ाइल में छोड़ने का प्रयास किया और इसने संदर्भ बनाया। मुझे लगता है कि मैं अब समझ गया हूं। ट्यूटोरियल अभी भी स्वागत किया। धन्यवाद!
हावर्डो

@ हेलो क्षमा करें, किसी भी ट्यूटोरियल का पता नहीं है। जब मैं वेब एसेंशियल रूट पर जाता हूँ, तो मैं अपने डोमेन मॉडल को एक क्लास लाइब्रेरी में, और अपने क्लाइंट साइड कोड में डुप्लिकेट .ts फाइलें बना रहा हूँ, मुझे आमतौर पर dto या vm मॉडल बनाने की ज़रूरत होती है, जिसे ब्राउज़र की आवश्यकता होती है के बारे में जानना। यदि आपको यह सब करने में समस्या आ रही है, तो टाइपराइटर एक्सटेंशन का प्रयास करें। यह आप कहीं भी आप चाहते हैं उर .ts मॉडल फ़ाइलों के लिए अनुमति देता है।
माइकल ट्रेंचिडा

15

प्रबलित की कोशिश करें। रूपरेखा तैयार करें। लगता है कि यह आपकी समस्या को हल करता है।

  1. इसे NuGet से इंस्टॉल करें
  2. अपने POCO पर नेविगेट करें और [TsInterface]इसके ऊपर विशेषता जोड़ें

    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. अपने प्रोजेक्ट का पुनर्निर्माण करें
  4. %Your_Project_Directory%/Scripts/project.tsफ़ाइल में उत्पन्न टाइपस्क्रिप्ट कोड का पता लगाएं और इसे मैन्युअल रूप से प्रोजेक्ट करने के लिए जोड़ें

    module YourNamespace {
        export interface IYourPoco
        {
            YourNumber: number;
            YourString: string;
            YourArray: string[];
            YourDictionary: { [key: int]: any };
        }
    }
  5. अपने सभी POCO और project.tsअपने अन्य टाइपस्क्रिप्ट कोड में संदर्भ के लिए भी ऐसा ही करें।

प्रलेखन विकी में अधिक विवरण देखें


सैंपल स्निपेट को केवल URL
Venkat.R

क्विकार्ट के साथ विकी है O_o github.com/reinanted/Rinin.Typings/wiki
Pavel B. Novikov

लेकिन ठीक है, मैं यहां एक उदाहरण प्रदान करूंगा :)
पावेल बी। नोविकोव

कोई .NET कोर समर्थन ( लिंक ) :(
एलेक्स

5
@AlexKlaus .NET कोर का समर्थन आ गया है
पावेल बी। नोविकोव

10

मैंने एक छोटी उपयोगिता बनाई है जो C # कक्षाओं से टाइपस्क्रिप्ट इंटरफेस उत्पन्न कर सकती है। एक NuGet पैकेज के रूप में उपलब्ध है । विस्तृत प्रलेखन परियोजना वेबपेज पर पाया जा सकता है ।


अच्छा पुस्तकालय, अच्छा प्रयास। दुर्भाग्य से उत्पादित मूल्य प्रकार को ट्विक करने का एक तरीका नहीं मिला, उदाहरण के लिए "स्ट्रिंग" को "नॉकआउटऑब्जर्वरटेबल स्ट्रिंग" या "स्ट्रिंग []" को "नॉकआउटऑब्जर्वरएबल ऐरे" में बदलें। क्या यह कुछ ऐसा है जो निकट भविष्य की योजनाओं में है?
रूट

2
मैंने इसके बजाय T4TS का उपयोग किया, इसमें 14 मिनट का समय लगा।
रूट

@root, आपको वास्तव में जनरेट की गई परिभाषाओं में एक स्ट्रिंग [] को नॉकआउटऑब्ज़र्वरएलेयर में परिवर्तित नहीं करना चाहिए। जब आप वास्तव में इन वर्गों के क्रमबद्ध उदाहरणों का उपभोग कर रहे हैं, तो आप इन उत्पन्न परिभाषाओं का उपयोग करते हैं। अब, आप मैपिंग प्लगइन के माध्यम से पूरे ऑब्जेक्ट को चला सकते हैं, लेकिन मैं इसके खिलाफ सावधानी बरतूँगा। यह अत्यधिक हो सकता है और मैं हमेशा सी # कक्षाओं के अपने अनुक्रमित उदाहरणों से मैन्युअल रूप से (शायद एक ctor के माध्यम से) रूपांतरों से भरे टाइपस्क्रिप्ट क्लासेस में कनवर्ट करना पसंद करता हूं । एकमात्र समय मैं सुझाव देता हूं कि मैं इसे अंधाधुंध तरीके से मैपिंग प्लगइन के माध्यम से चला रहा हूं।
एलन राइस

@ लुकास केब्रत, टाइपलाइट के लिए बहुत बहुत धन्यवाद, यह हमारी परियोजनाओं में बेहद फायदेमंद रहा है और मैंने इसके बारे में संक्षेप में यहां लिखा है: पानी के नीचे
एलन चावल

@AllenRice, मुझे हाथ से तैयार किए गए नॉकआउट व्यू-मॉडल क्लासेस का काम करना आसान लगा, जो कि मैं आपको अप्रोच किए गए दृष्टिकोण का उपयोग करता हूं और इसे एक ऑटो जेनरेटेड क्लास के साथ जोड़ देता हूं जो डीटीओ है जो मैपिंग प्लगइन के माध्यम से पारित किया गया था।
रूट

7

कृपया इस लाइब्रेरी टाइपराइटर पर एक नज़र डालें

यह न केवल वर्गों, एनम, इंटरफेस आदि को परिवर्तित करता है, बल्कि एपी-कंट्रोलर भी है, जो कि बस कमाल है।

साथ ही यह ऐसा करता है जैसे ही आप स्रोत .cs फ़ाइल को सहेजते हैं, इसलिए मुझे किसी भी बाहरी टूल को ट्रिगर करने की आवश्यकता नहीं है। .Cs को सहेजें और आप अपडेट .ts


बड़ी बात यह है कि यह संबंधित CS फ़ाइलों को सहेजने पर TS फ़ाइलों का उत्पादन करता है। हालांकि, आउटपुट फ़ोल्डर की स्थापना काफी नाजुक है ( यहां चर्चा देखें ) और कुछ हाथ से तैयार किए गए कोड की आवश्यकता है।
एलेक्स

मैं उस के लिए बिल्ड टूल्स का उपयोग करता हूं, और यह उपकरण यहां बताए गए तरीके से अधिक शक्तिशाली है
harishr

6

मेरे पास एक छोटा सा समाधान है जो T4 टेम्पलेट्स ( स्रोत देखें ) का उपयोग करता है ।

आप किसी भी CLR POCO से जाएं:

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

टाइपस्क्रिप्ट इंटरफ़ेस के लिए:

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

3

आप ओपन-सोर्स प्रोजेक्ट NSwag का उपयोग कर सकते हैं : GUI में, आप एक मौजूदा .NET DLL से .NET क्लास का चयन कर सकते हैं और इसके लिए टाइपस्क्रिप्ट इंटरफ़ेस उत्पन्न कर सकते हैं।

परियोजना कमांड लाइन टूल और टी 4 टेम्प्लेट के साथ-साथ वेब एपीआई नियंत्रकों के लिए क्लाइंट कोड का निर्माण भी प्रदान करती है ...


ज्ञात हो, कि NSwag टीएस फाइलें केवल या तो बाइनरी फाइलों (आपको अपने बायनेरिज़ के सभी निर्भरता की आवश्यकता होती है) या इसकी JSON फ़ाइल से उत्पन्न होगी, जो स्वैगर बाइनरी फ़ाइलों से उत्पन्न होती है।
एलेक्स

3

यदि आपको हर जेनरेट किए गए टाइपस्क्रिप्ट क्लास / इंटरफेस के लिए एक अलग फाइल बनाने की जरूरत है (यानी "फाइल में एक सिंगल क्लास" तरीके से), तो आप टाइपगैन को आजमा सकते हैं । यह एक टूल है जिसका उपयोग आप पैकेज मैनेजर कंसोल से अपने C # क्लासेस / एनम के आधार पर टाइपस्क्रिप्ट फाइलें तैयार करने के लिए कर सकते हैं। यह वर्तमान में समर्थन करता है:

  • एनामस निर्यात करना; TS वर्ग या इंटरफेस के रूप में POCOs का निर्यात करना
  • विरासत
  • सामान्य प्रकार
  • संग्रह / नेस्टेड संग्रह प्रकार

प्लस कुछ अतिरिक्त सुविधाएँ। यह खुला स्रोत भी है (आप इसे गीथूब पर देख सकते हैं )।


2

आसपास के अन्य तरीके के बारे में कैसे?

टाइपस्क्रिप्ट ट्रांसलेटर टाइप करें । यह C # समर्थन पर जाने के लिए तैयार है, लेकिन वास्तव में टेम्पलेट-आधारित है (प्रतिपादन के लिए Nunjucks का उपयोग करता है), जिसका अर्थ है कि यह कुछ और भी उत्पन्न कर सकता है - VB.NET, F #, C ++, XML, SQL - जो भी आप टेम्पलेट के साथ एन्कोड कर सकते हैं।

.NET कंसोल प्रोग्राम के रूप में काम करता है, NodeJS प्रोग्राम (विंडोज पर उन लोगों के लिए नहीं), या एक दृश्य स्टूडियो एक्सटेंशन के रूप में , जेनरेट-ऑन-सेव कार्यक्षमता के साथ पूरा होता है। और MSBuild समर्थन भी शामिल है, बस अपने बिल्ड सर्वर को खुश करने के लिए। :-)


मैंने इसे +1 किया क्योंकि यह वास्तव में सबसे अच्छा समाधान है, जेनरेट-ऑन-सेव किलर फीचर है।
जॉन ज़ब्रोस्की

2

आप इसका उपयोग भी कर सकते हैं: https://github.com/pankleks/TypeScriptBuilder

यह छोटी लाइब्रेरी C # प्रकारों के आधार पर टाइपस्क्रिप्ट टाइप परिभाषा उत्पन्न करती है। अपने बैकएंड टाइपस्क्रिप्ट प्रोजेक्ट के लिए कोड जनरेट करने के लिए इसे सीधे अपने बैकेंड C # प्रोजेक्ट में उपयोग करें। प्री-बिल्ड टूल्स द्वारा कोड जनरेट करने के लिए, आप छोटे कंसोल ऐप भी लिख सकते हैं।

पूर्ण और नेट कोर ढांचे पर काम करता है!

नगेट द्वारा स्थापित करें: Install-Package TypeScriptBuilder

समर्थित सुविधाएँ

  • प्रकार निर्भरता का समाधान
  • जेनेरिक्स
  • टाइप इनहेरिटेंस
  • नाम स्थान (मॉड्यूल)
  • enums
  • अशक्त प्रकार के
  • शब्दकोश अभिसरण (मजबूत प्रकार टीएस अनुक्रमित वस्तुओं के लिए)
  • कोड पीढ़ी नियंत्रण विशेषताओं का सेट
  • any उन प्रकारों के लिए जिन्हें परिवर्तित नहीं किया जा सकता है

अधिक विवरण: https://github.com/pankleks/TypeScriptBuilder/blob/master/README.md


बस कोशिश की TypeScriptBuilderऔर यह अब तक उत्कृष्ट लग रहा है; .NET कोर समर्थन के लिए हुर्रे!
टोबियास जे

1

दोस्तों की नजर https://github.com/reinanted/ Reinlied.Typings पर है । मैं पिछले कुछ दिनों से टाइपलाइट और t4 टेम्प्लेट के साथ खेल रहा हूं और इस परियोजना के साथ समाप्त हुआ। यह सुपर-सिंपल है और आकर्षण की तरह काम करता है। बस पैकेज प्राप्त करें, कॉन्फ़िगरेशन फ़ाइल को संशोधित करें (यह 10 सेकंड के लिए जैसा है) और निर्माण करें। बिना किसी मुद्दे के सभी अपने आप हो जाते हैं। लेखक को आशीर्वाद!

T4 टेम्प्लेट्स के बारे में बुरी बात यह है कि एक बार जब आप VS से निर्माण करते हैं तो स्कैन की हुई असेंबली लॉक हो जाती हैं और आपको VS (कितनी अच्छी तरह यह है?) को पुनरारंभ करना होगा। T4 टूलबॉक्स में कुछ वर्कअराउंड + कुछ वीएस सफाई निर्देश हैं लेकिन इनमें से किसी ने भी मेरे लिए काम नहीं किया।


1

मुझे शहरकी समाधान पसंद है। मैंने इसे थोड़ा बढ़ाया था। तो, समाधान भी T4 टेम्प्लेट के साथ कोडरेशन तकनीक पर आधारित है।

यह सामान्य टाइपस्क्रिप्ट प्रकार और परिवेश घोषणाएँ उत्पन्न कर सकता है।

यह वंशानुक्रम और इंटरफ़ेस कार्यान्वयन का समर्थन करता है।

प्रकार के क्षेत्र के रूप में जेनरिक, सरणियों और सूचियों का समर्थन करता है।

इसके अलावा यह टाइपस्क्रिप्ट प्रकारों में अनुवाद करता है जो स्पष्ट रूप से कॉन्फ़िगरेशन में उल्लिखित नहीं है (उदाहरण के लिए हम टाइप ए आयात करते हैं, और टीएस आउटपुट में आप कुछ अन्य प्रकार: फ़ील्ड के प्रकार, आधार प्रकार और इंटरफेस) पा सकते हैं।

आप टाइप के नाम को ओवरराइड भी कर सकते हैं।

एनम भी समर्थित हैं।

उपयोग उदाहरण (आप इसे प्रोजेक्ट रिपॉजिटरी में पा सकते हैं):

// 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" #>

और आपको एक आउटपुट मिलेगा

//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
}

पूर्ण समाधान यहां देखें: https://bitbucket.org/chandrush/cst4ts


1

आप Bridge.net का उपयोग भी कर सकते हैं। संस्करण 1.7 से यह C # प्रकारों के लिए टाइपस्क्रिप्ट परिभाषा की पीढ़ी का समर्थन करता है। Http://bridge.net/docs/generate-typescript-definitions/ देखें


मुख्य समस्या यह है कि जब आप Google खोज करते हैं तो आप मूल प्रश्न पर उतर सकते हैं और कभी ध्यान नहीं देते हैं कि उपयोगी जानकारी डुप्लिकेट / बंद उत्तर में मौजूद है
जॉर्ज बिरबिलिस

इसलिए सुनिश्चित करें कि कैनोनिकल में सबसे अच्छी जानकारी है। एकाधिक प्रश्नों पर पोस्ट न करें। इस पर कोई आगे की चर्चा के लिए लिया जा सकता है मेटा स्टैक ओवरफ़्लो
मार्टिन पीटर्स

1

मुझे @ शहरकी का उत्तर भी बहुत पसंद आया, इसलिए मैंने इसे एक बार में पूरे नाम स्थान पर करने के लिए बढ़ाया। POCO क्लासेस को नामस्थान में रखें, और T4 टेम्प्लेट का पुनर्निर्माण करें। काश मैं जानता हूं कि प्रत्येक के लिए अलग-अलग फाइलें कैसे उत्पन्न की जाएं, लेकिन यह दुनिया का अंत नहीं है।

आपको शीर्ष भाग में .DLL फ़ाइलों (जहाँ आप चाहते हैं कि कक्षाएं हैं) को संदर्भित करने की आवश्यकता है, और आपको नामस्थानों का उल्लेख करने की आवश्यकता है। संपादित करने के लिए सभी लाइनें ACME के ​​साथ चिह्नित हैं। @Citykid को मेजर कुडोस, इसकी सराहना!

<#@ 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();
    }
#>

0

मेरा समाधान एक छोटे कोडेजेन उपयोग को लिखना था जो बस एक प्रोजेक्ट असेंबली (और असेंबली का उल्लेख करते हुए) लेता है और उन प्रकारों को स्कैन करना शुरू करता है जो टाइपस्क्रिप्ट और सी # के बीच बातचीत में शामिल हैं। यह उपयोग दोनों जावास्क्रिप्ट को d.ts के रूप में आउटपुट करता है ... टूल को पोस्ट-बिल्ड इवेंट में कहा जाता है ... एक आकर्षण की तरह काम करता है!


मुझे नहीं पता कि मैंने आउटपुट js और d.ts को क्यों चुना ... अभी यह केवल आउटपुट .ts ... सीधा और बहुत ही उल्लेखनीय है।
पॉल0515

1
हाय पॉल ... क्या आप हमारे साथ उपयोग कोड साझा कर पाएंगे। मैं सिर्फ एक ts फ़ाइल (एक निश्चित फ़ोल्डर स्थान पर) बनाने के लिए देख रहा हूँ, न कि d.ts फ़ाइल जैसा आपने कहा है। क्या आपका उपयोग कुछ ऐसा कर सकता है ??
कृष्ण तेजा वीरमचन्नी

0

यदि रुचि है, तो आप TypedRpc उपयोग कर सकते हैं । इसका उद्देश्य केवल टाइपस्क्रिप्ट में इंटरफेस बनाना नहीं है, बल्कि JsonRpc प्रोटोकॉल का उपयोग करके .Net में सेवा के साथ सभी संचार बनाना है।

सर्वर में एक वर्ग के लिए उदाहरण:

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

उत्पन्न टाइपस्क्रिप्ट कोड का उपयोग:

/// <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);

की जाँच करें https://github.com/Rodris/TypedRpc कि यह कैसे उपयोग करने के लिए के अन्य उदाहरण के लिए।


0

ASP.NET वेब API क्लाइंट जेनरेटर SDLC के दौरान स्वैगर टूलचिन और अन्य की तुलना में अधिक उपयोगी, कम ओवरहेड हो सकता है।

जबकि प्रोग्रामर आम तौर पर क्लाइंट एपीआई कोड जनरेट करने के लिए WebApiClientGen का उपयोग करते हैं, यह प्रोजेक्ट POCO2TS.exe, एक कमांड लाइन प्रोग्राम भी प्रदान करता है, जो POCO क्लासेस से टाइपस्क्रिप्ट इंटरफेस बनाता है। आप अपने निर्माण पाइपलाइन के साथ कोड पीढ़ी को एकीकृत करने के लिए या तो Poco2ts.exe या poco2ts घटक का उपयोग कर सकते हैं।


0

यदि आप इसे node.js के माध्यम से परिवर्तित करना चाहते हैं तो आप इस पैकेज (csharp-to-typecript) का उपयोग कर सकते हैं। 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;
}

0

यदि आप VSCode का उपयोग कर रहे हैं, तो आप उस एक्सटेंशन C # से टाइपस्क्रिप्ट पर एक नज़र डाल सकते हैं

C # क्लास को टाइपस्क्रिप्ट इंटरफ़ेस में बदलें

देखें कि कैसे मैं इसे सी # कोड से केवल एक क्लिक में परिवर्तित कर सकता हूं। बेशक, सभी वर्गों को कारखाने के रूप में परिवर्तित नहीं किया जाएगा, लेकिन यह क्लाइंट-साइड के लिए पर्याप्त है। हमें केवल डेटा के आकार की आवश्यकता है। कभी-कभी यदि मुझे विज़िटर पैटर्न का उपयोग करने की आवश्यकता होती है, तो मुझे अतिरिक्त तरीकों से सजना होगा जो मुझे चाहिए। ऐसा करने में केवल 5 सेकंड का समय लगा। एक मिनट ऊपर की तुलना में, मैं कह सकता हूं कि यह एक बड़ी जीत है।

मेरे ब्लॉग पोस्ट में और अधिक विवरण देखें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.