LoginSignup
6
5

More than 5 years have passed since last update.

DTOからTypeScript定義をT4で自動生成

Posted at

概要

サーバ側で定義したDTOとかTypeScriptでも同じように型定義するのが冗長でだるい。

解決方法

TypeLiteを使う
T4で指定したクラスをTypeScriptのインタフェースに変換してくれる

使い方

DTOにTsClassAttributeを付ける(最低限モジュール名)

DTO
    [TsClass(Module = "ModuleName")]
    public class HogeDto
    {
        public int Value { get; set; }
        public HogeType Type { get; set; }
    }

    [TsEnum(Module = "ModuleName")]
    public enum HogeType
    {
        Fuga = 1,
        Moge = 2
    }

ビルドしてからT4実行で生成

以下自動生成される内容

t4.d.ts
declare module ModuleName {
    interface IHogeDto {
        value: number;
        type: ModuleName.HogeType;
    }
}
t4.enums.d.ts
module ModuleName {
    export enum HogeType {
        Fuga = 1,
        Moge = 2
    }
}

Tips

BugFix

デフォルトのT4の状態だと少しバグってるっぽいので、
以下の拡張メソッドに置き換える

TypeScriptFluentExtensions
        public static TypeScriptFluent ForExecutingAssemblies(this TypeScriptFluent ts)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var types = assembly.GetTypes().Where(x => x.GetCustomAttributes(typeof (TsClassAttribute)).Any());
            foreach (var type in types)
                ts.For(type);

            return ts;
        }

これを

呼び出し元のT4
TypeScript.Definitions().ForLoadedAssemblies()

こうする

呼び出し元のT4
TypeScript.Definitions().ForExecutingAssemblies()

チュートリアルが信用ならない件

公式のチュートリアルが古い実装(Obsolete)なので最新の実装に変える

インタフェース名をIプレフィックスが付くようにする

公式
WithFormatter((type, f) => "I" + ((TypeLite.TsModels.TsClass)type).Name)
最新
.WithTypeFormatter((type, formatter) => "I" + ((TypeLite.TsModels.TsClass)type).Name)

CamelCase対応

公式
.WithFormatter((TypeLite.TsModels.IMemberIdentifier identifier) => 
       Char.ToLower(identifier.Name[0]) + identifier.Name.Substring(1)
   )

最新
.WithMemberFormatter((identifier) => Char.ToLower(identifier.Name[0]) + identifier.Name.Substring(1));

Nullableにしたい

TsPropertyAttributeでIsOptional = trueにする

DTO
    [TsClass(Module = "ModuleName")]
    public class HogeDto
    {
        [TsProperty(IsOptional = true)]
        public int Value { get; set; }
        public HogeType Type { get; set; }
    }
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5