Typelite:如何使用T4转换将可空C#类型设置为可空的Typescript类型?

时间:2014-09-26 06:37:51

标签: reflection typescript t4 system.reflection typelite

我正在使用Typelite 9.5.0将我的C#类转换为Typescript接口。我想要一个可以为空的类型(例如Guid?)在Typescript中转换为可空类型。

目前我有这个C#类:

public class PersistentClassesReferences
{
public Guid? EmailMessageId { get; set; }
public Guid? FileMetaDataId { get; set; }
public Guid? IssueId { get; set; }
public Guid? ProjectId { get; set; }
}

但是使用Typelite将其转换为此Typescript接口:

interface IPersistentClassesReferences {
    EmailMessageId : System.IGuid;
    FileMetaDataId : System.IGuid;
    IssueId : System.IGuid;
    ProjectId : System.IGuid;
}

但是当我想从这个接口创建一个新的typescript变量时,编译器在我没有设置所有属性时会抱怨(某些值为null)。

因此,我有一个模板,可以测试可空类型,如果是这样,会添加一个?

var isNullabe = Nullable.GetUnderlyingType(tsprop.ClrProperty.PropertyType) != null;
if (isNullabe)
{
    return identifier.Name + "? ";
}

这确实有效,但现在不行了(我想在升级到Typelite 9.5.0或其他一些nugetpackage更新之后)。

我收到错误消息:

 Compiling transformation: 'System.Reflection.MemberInfo' does not contain a
 definition for 'PropertyType' and no extension method 'PropertyType' accepting
 a first argument of type 'System.Reflection.MemberInfo' could be found (are you
 missing a using directive or an assembly reference?)           

如何在标识名中添加问号?

4 个答案:

答案 0 :(得分:9)

您可以使用TsProperty属性创建它,例如以下C#代码将产生一个可选属性:

[TsClass]
public class Person
{
    [TsProperty(IsOptional=true)]
    public string Name { get; set; }
    public List<Address> Addresses { get; set; }
}

这将生成以下TypeScript定义

interface Person {
    Name?: string;
    Addresses: TypeScriptHTMLApp1.Address[];
}

您可以在此处找到有关此内容的更多信息:docs

请在此处查看代码:code

答案 1 :(得分:3)

如果您想使用TypeLite格式化器,这应该可以工作:

var propertyInfo = tsprop.ClrProperty as PropertyInfo;
var propertyType = propertyInfo != null ? propertyInfo.PropertyType : ((FieldInfo)tsprop.ClrProperty).FieldType;    
var isNullabe = Nullable.GetUnderlyingType(propertyType) != null;
if (isNullabe) {
    return identifier.Name + "? ";
}

答案 2 :(得分:2)

回应卢卡斯的回答:

任何阅读此内容并使用更高版本的TypeLite的人都会发现TsProperty不再具有名为ClrProperty的属性。它现在称为MemberInfo(并且是MemberInfo类型)。

这是一个MemberFormatter的示例,它将可以为空的C#类型转换为可选的TypeScript属性。它还使成员骆驼案件命名为:

.WithMemberFormatter((identifier) => {
    var tsprop = identifier as TsProperty;

    if (tsprop != null)
    {
        var clrProperty = tsprop.MemberInfo as PropertyInfo;
        var isNullabe = Nullable.GetUnderlyingType(clrProperty.PropertyType) != null;
        if (isNullabe)
        {
            return Char.ToLower(identifier.Name[0]) + identifier.Name.Substring(1) + "?";
        }
    }

    return Char.ToLower(identifier.Name[0]) + identifier.Name.Substring(1);
});

答案 3 :(得分:0)

好消息是你不需要这样做,因为TypeScript中的?修饰符实际上使整个成员成为结构类型比较的可选项。由于您只想使类型为可空,因此您需要执行任何操作,因为您可以将TypeScript中的任何类型归零:

var a: number = null;
var b: boolean = null;
var c: string = null;
var d: string[] = null;
//... and so on

以下是?如何在TypeScript中工作的演示(它与可空性无关):

interface Example {
    a?: string;
    b: string;
}

var both = { a: '', b: '' };
var onlyB = { b: '' };
var onlyA = { a: '' };

function doExample(x: Example) {
    return x;
}

// Fine
doExample(both);

// Fine
doExample(onlyB);

// Not fine - compiler warning
doExample(onlyA);

当编译器检查传递给doExample的参数时,它将允许省略a属性,因为它具有?。必须提供b属性。