none
TypeScript モデルのコンストラクタの記述方法について new Model{key:vlaue, key:value}としたい RRS feed

  • 質問

  • TypeScriptでモデルを使っているのですが、思うようなコーディングがかけなくて困っています。

    ↓この記載方法がかけない。
    var member = new Models.Member{Name :"ほげたろう", EMail:"hoge@hoge.com"};

    JavaScriptの時は、
    var m = {Name:"", Email:""};
    とやってオブジェクト化していたのですが、クラス(またはインターフェース)を作って制約を設けたTypeScriptのコーディングに変更するとC#やJavaScriptのような{key:value, key:value,,}での記載が出来ずに困っています。

    なにかやり方があるのでしょうか?

    ▼TypeScript

    module Models {
        export interface IMember {
            Name: string;
            Email: string;
            Birth: Date;
            Married: boolean;
            Price: number;
            Memo: string;
        }

        export class Member {
            constructor();
            constructor(model: IMember = {Name : "", Email :"", Birth:new Date(), Married : false, Price : 0, Memo : ""}) {
                if (model !== undefined) {
                    if (model.Name !== undefined) this.Name = model.Name;
                }
            }
            public Name: string;
            public Email: string;
            public Birth: Date;
            public Married: boolean;
            public Price: number;
            public Memo: string;

            //WebAPIからC#のモデルを受け取るとタイプエラーが発生するので、削除       
            //ToString(): string {
            //    return "Name=" + this.Name + ", Emal=" + this.Email + ", Birth=" + this.Birth;
            //}
        }
    }


    module Models2 {
        export class Member {
            constructor();
            constructor(model?: Member) {
                if (model !== undefined) {
                    if (model.Name !== undefined) this.Name = model.Name;
                }
            }
            public Name: string;
            public Email: string;
            public Birth: Date;
            public Married: boolean;
            public Price: number;
            public Memo: string;

            //WebAPIからC#のモデルを受け取るとタイプエラーが発生するので、削除
            //ToString(): string {
            //    return "Name=" + this.Name + ", Emal=" + this.Email + ", Birth=" + this.Birth;
            //}
        }
    }


    ▼C#

    namespace WebApplication.Models
    {
     public class Member
     {
      public int Id { get; set; }
      [DisplayName("氏名")]
      public string Name { get; set; }
      
      [DisplayName("メールアドレス")]
      [EmailAddress(ErrorMessage="メールアドレスの形式で入力してくださいね。")]
      public string Email { get; set; }
      [DisplayName("生年月日")]
      public DateTime Birth { get; set; }
      [DisplayName("既婚")]
      public bool Married { get; set; }
      [DisplayName("価格")]
      public decimal Price { get; set; }
      [DisplayName("備考")]
      public string Memo { get; set; }

      public override string ToString()
      {
       StringBuilder sb = new StringBuilder();
       sb.Append("{");
       sb.Append("Id=" + Id);
       sb.Append(", Name=" + Name);
       sb.Append(", Email=" + Email);
       sb.Append("}");
       return sb.ToString();
      }
     }
    }

    ↓1行でオブジェクトを生成可能
    var member = new Member{Name = "ほげたろう", EMail="hoge@hoge.com"};

    2014年12月10日 4:07

回答

  • #最終的に実現されたいことをつかみかねているので、回答として外しているかもしれないのですが……。

    まず、TypeScriptもJavaScriptと同様にオブジェクトリテラルで記述できますので、以下は有効だと思います。

    var m1 = { Name : "", Email :"", Birth:new Date(), Married : false, Price : 0, Memo : ""};


    また、以下のインタフェースがあるとして、

    interface IMember {
        Name: string;
        Email: string;
        Birth: Date;
        Married: boolean;
        Price: number;
        Memo: string;
    }


    型を意識するのであれば、変数に型アノテーションを指定して、

    var m2 : IMember = { Name : "", Email :"", Birth:new Date(), Married : false, Price : 0, Memo : ""};
    という記述ができます。




    また、TypeScriptは構造的部分型(構造的サブタイピング)という機能があります。
    『明示的に型アノテーションが書かれていなくてもメンバが一致していれば同じ型とみなす』という、いわゆるダックタイピングな感じです。

    ですので、クラスを以下のように定義しておくと、

    class Member {
        constructor(model?: IMember) {
            if (model !== undefined) {
                if (model.Name !== undefined) this.Name = model.Name;
            }
        }
        public Name: string;
        public Email: string;
        public Birth: Date;
        public Married: boolean;
        public Price: number;
        public Memo: string;
    }

    以下は何れも同じように動作するはずです。

    var member1 = new Member(m1);
    var member2 = new Member(m2);
    var member3 = new Member({Name : "", Email :"", Birth:new Date(), Married : false, Price : 0, Memo : ""});



    きよくらならみ

    • 回答としてマーク kiyo7447R2 2014年12月10日 9:45
    2014年12月10日 6:50

すべての返信

  • 回答でなくてすみません。

    目的はどういったことでしょう? 差し支えなければ、全体的なシナリオを含めてやりたいことを書いていただけませんか?

    ASP.NET Web API アプリで、Put とか Post メソッドが引数として受け取るオブジェクトを、ブラウザから jQuery.ajax などを使って JSON 文字列として送信する際、その JSON 文字列をどうやって組み立てるかという話ですか?

    2014年12月10日 6:34
  • #最終的に実現されたいことをつかみかねているので、回答として外しているかもしれないのですが……。

    まず、TypeScriptもJavaScriptと同様にオブジェクトリテラルで記述できますので、以下は有効だと思います。

    var m1 = { Name : "", Email :"", Birth:new Date(), Married : false, Price : 0, Memo : ""};


    また、以下のインタフェースがあるとして、

    interface IMember {
        Name: string;
        Email: string;
        Birth: Date;
        Married: boolean;
        Price: number;
        Memo: string;
    }


    型を意識するのであれば、変数に型アノテーションを指定して、

    var m2 : IMember = { Name : "", Email :"", Birth:new Date(), Married : false, Price : 0, Memo : ""};
    という記述ができます。




    また、TypeScriptは構造的部分型(構造的サブタイピング)という機能があります。
    『明示的に型アノテーションが書かれていなくてもメンバが一致していれば同じ型とみなす』という、いわゆるダックタイピングな感じです。

    ですので、クラスを以下のように定義しておくと、

    class Member {
        constructor(model?: IMember) {
            if (model !== undefined) {
                if (model.Name !== undefined) this.Name = model.Name;
            }
        }
        public Name: string;
        public Email: string;
        public Birth: Date;
        public Married: boolean;
        public Price: number;
        public Memo: string;
    }

    以下は何れも同じように動作するはずです。

    var member1 = new Member(m1);
    var member2 = new Member(m2);
    var member3 = new Member({Name : "", Email :"", Birth:new Date(), Married : false, Price : 0, Memo : ""});



    きよくらならみ

    • 回答としてマーク kiyo7447R2 2014年12月10日 9:45
    2014年12月10日 6:50
  • ありがとうございました。できました。回答は求めているものでした。

    頂いたアドバイスを参考に初期値やプロパティを任意にするなどして思うような制御ができました。

            var member3 = new Models3.Member({ Name: "たろう", Email: "hoge@hoge.com", Birth: new Date(), Married: false, Memo:"", Price : 120});
    
            alert("Name:" + member3.Name + ", Email:" + member3.Email);
            //Name:たろう, Email:hoge@hoge.com
            var m2: Models3.IMember = { Name: "はなこ" };
            var member4 = new Models3.Member(m2);
    
            alert("Name:" + member4.Name + ", Email:" + member4.Email);
            //Name:はなこ, Email:none email
    
            var member5 = new Models3.Member();
    
            alert("Name:" + member5.Name + ", Email:" + member5.Email);
            //Name:init name, Email:init email

    module Models3{
        export interface IMember {
            Name?: string;
            Email?: string;
            Birth?: Date;
            Married?: boolean;
            Price?: number;
            Memo?: string;           
        }
        export class Member {
            constructor(model: IMember = { Name: "init name", Email: "init email", Birth: new Date(), Married: false, Price: 0, Memo: "" }) {
                if (model !== undefined) {
                    if (model.Name !== undefined) this.Name = model.Name; else this.Name = "none name";
                    if (model.Email !== undefined) this.Email = model.Email; else this.Email = "none email";
                }
            }
            public Name: string;
            public Email: string;
            public Birth: Date;
            public Married: boolean;
            public Price: number;
            public Memo: string;
        }
    
    }



    2014年12月10日 9:47