There is not currently anything that will map C# to TypeScript. If you have a lot of POCOs or you think they might change often, you could create a converter - something simple along the lines of...
public class MyPoco {
public string Name { get; set; }
}
To
export class MyPoco {
public Name: string;
}
There is also a discussion on Codeplex about auto-generating from C#.
Just to keep things updated, TypeLite can generate TypeScript interfaces from C#:
http://type.litesolutions.net/
Web Essentials allow to compile C# files to TypeScript .d.ts
files on save. Then you could reference the definitions from your .ts
files.
If you use vscode you can use my extension csharp2ts which does exactly that.
You just select the pasted C# code and run the Convert C# to TypeScript
command from the command palette
A conversion example:
public class Person
{
/// <summary>
/// Primary key
/// </summary>
public int Id { get; set; }
/// <summary>
/// Person name
/// </summary>
public string Name { get; set; }
}
to
export interface Person
{
/**Primary key */
Id : number;
/**Person name */
Name : string;
}
TypeLite and T4TSs above both looked good, just picked one, TypeLite, forked it to get support for
Then I needed C# interfaces and thought it is time to bake my own thing and wrote a simple T4 script that just does what I need. It also includes Enums. No repo required, just < 100 lines of T4.
Usage
No library, no NuGet, just this plain simple T4 file - use "add item" in Visual Studio and choose any T4 template. Then paste this into the file. Adapt every line with "ACME" in it. For every C# class add a line
<#= Interface<Acme.Duck>() #>
Order matters, any known type will be used in follwing interfaces. If you use only interfaces, the file extension can be .d.ts, for enums you need a .ts file, since a variable is instantiated.
Customisation
Hack the 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();
}
#>
The next level of the script will be to create the service interface from the MVC JsonController class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With