pab*_*ndo 111 javascript typescript
我将开始TypeScript
在我的HTML客户端项目中使用,该项目属于具有实体框架域模型的MVC项目.我希望我的两个项目(客户端和服务器端)完全分离,因为两个团队将在此工作...... JSON和REST用于来回传递对象.
当然,我domain
在客户端的对象应该与服务器端的对象匹配.在过去,我通常手动完成此操作.有没有办法重用我的C#类定义(特别是POJO
我的域模型中的类)来在TypeScript中创建相应的类"?
Fen*_*ton 53
目前没有任何将C#映射到TypeScript的东西.如果您有很多POCO或者您认为它们可能经常更换,您可以创建一个转换器 - 简单的......
public class MyPoco {
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
至
export class MyPoco {
public Name: string;
}
Run Code Online (Sandbox Code Playgroud)
只是为了保持更新,TypeLite可以从C#生成TypeScript接口:
http://type.litesolutions.net/
V.B*_*.B. 34
Web Essentials允许.d.ts
在保存时将C#文件编译为TypeScript 文件.然后,您可以引用.ts
文件中的定义.
cit*_*kid 22
上面的TypeLite和T4TS看起来都很好,只选了一个,TypeLite,分叉它以获得支持
然后我需要C#接口,并认为是时候烘焙我自己的东西并写了一个简单的T4脚本,只是做我需要的.它还包括Enums.不需要回购,只需<100行T4.
用法
没有库,没有NuGet,只是这个简单的简单T4文件 - 在Visual Studio中使用"添加项目"并选择任何T4模板.然后将其粘贴到文件中.使用"ACME"调整每一行.为每个C#类添加一行
<#= Interface<Acme.Duck>() #>
Run Code Online (Sandbox Code Playgroud)
订单很重要,任何已知的类型都将用于以下接口.如果仅使用接口,则文件扩展名可以是.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();
}
#>
Run Code Online (Sandbox Code Playgroud)
该脚本的下一级将是从MVC JsonController类创建服务接口.
Raf*_*ael 17
如果你使用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; }
}
Run Code Online (Sandbox Code Playgroud)
至
export interface Person
{
/**Primary key */
Id : number;
/**Person name */
Name : string;
}
Run Code Online (Sandbox Code Playgroud)
Pav*_*kov 13
试试Reinforced.Typings框架.似乎它解决了你的问题.
导航到您的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; }
}
}
Run Code Online (Sandbox Code Playgroud)在%Your_Project_Directory%/Scripts/project.ts
文件中找出生成的TypeScript代码,并手动将其添加到项目中
module YourNamespace {
export interface IYourPoco
{
YourNumber: number;
YourString: string;
YourArray: string[];
YourDictionary: { [key: int]: any };
}
}
Run Code Online (Sandbox Code Playgroud)project.ts
在其他TypeScript代码中引用.在文档维基中查看更多详细信息
我有一个使用T4模板的小解决方案(查看源代码).
你去任何CLR POCO:
public class Parent : Person
{
public string Name { get; set; }
public bool? IsGoodParent { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
到TypeScript接口:
///<reference path="Child.d.ts" />
///<reference path="Person.d.ts" />
interface Parent extends Person {
Name : string;
IsGoodParent? : bool;
Children : Child[];
}
Run Code Online (Sandbox Code Playgroud)
小智 5
如果您需要为每个生成的 TypeScript 类/接口创建一个单独的文件(即以“每个文件一个类”的方式),您可以尝试TypeGen。您可以从包管理器控制台使用它来根据 C# 类/枚举生成 TypeScript 文件。目前它支持:
加上一些附加功能。它也是开源的(你可以在github上查看)。
归档时间: |
|
查看次数: |
59351 次 |
最近记录: |