2015-12-30 4 views
6

これは私が何をしようとしているのがより簡単な例です:クラスを使用してJSONオブジェクトをタイプコピー型の変数にキャストする正しい方法はありますか?

export class Person{ 
    id:Number; 
    name:String; 
} 

export class PersonForm{ 

    // This line: 
    default:Person = {name: "Guy"}; 
    // Gives the following error: 
    // Error:(25, 5) TS2322: Type '{ name: string; }' is not assignable to type 'Person'. 
    // Property 'id' is missing in type '{ name: string; }'. 

    // I tried <Person>{name: "Guy"} but it gives the same error. 

} 

どのように私は、コンパイラは限りイムは、非existantプロパティを使用していないとして、この問題を無視することができ、またはどのように私はクラスを宣言しますだから私は新しいPerson()の代わりにこのように割り当てを行い、次に私が望むプロパティを設定することができます。

注:すべてのプロパティを持つオブジェクトをコンストラクタに送信することは、私が期待している解決策ではありません。私はオプションのフィールドを宣言することができるので、インターフェイスを使用しても、私はクラスで同じことを行うことができますか?クラス(ないインターフェイス)を宣言するための最良の方法を探す

ので、私はきれいなコードでそれを初期化することができます:私が達成しようとしているものの

主な目標:

は、いくつかのより多くの情報を追加します設定したいパラメータだけを1行に設定します。 Javaでは、コンストラクタをオーバーロードするか、Builderパターンを使用します。

私は確かにビルダーパターンを試すことができましたが、もしあれば、より多くのタイプスクリプトの方法を探しています。

+1

このシナリオでは、インタフェースを使用してと間違って何?最高のフィット感のようです。 – toskv

+1

あなたのオプションは、オプションのプロパティを持つインターフェイスを作成し、クラスがインターフェイスを実装するか、またはコンストラクタパラメータとしてインターフェイスを受け入れるようにすることだと思います。現時点では、あなたが望むことをする方法はありませんが、[他の人は](https://github.com/Microsoft/TypeScript/issues/4889)それについて質問しました。 –

+0

代わりに、クラスのコンストラクタを作成してヌルパラメータで呼び出すこともできます。ただし、この場合でもインタフェースはさらに優れています。 – toskv

答えて

3

私はそれを行うための最も簡単な方法を発見し、それは可能です。私はこれまでにこの方法で試したことがあると思いますが、数字 "&"の代わりに "数字" & "string"を使用していたのですが、コンパイラから誤ったエラーが出る可能性があります。私にとっては:

export class Person{ 
    constructor(
     public id?: number, // make sure you use number and string types instead of Number and String types 
     public name?: string // make sure you make all properties optional using "?" 
    ){} 
} 

export class PersonForm{ 
    default:Person = <Person>{name: "Guy"}; 
} 
+0

' {名前:" Guy "} instanceof Person; // false' –

+0

@JohnWhite yea、{name: "Guy"}の型はObjectです。Personのインスタンスが必要な場合は、コンストラクタを呼び出す必要があります: 'new Person()' – Langley

0

あなたはクラスをコンストラクタで書くことができます。

export class Person { 
    constructor(public id: number, public name: string) {} 
} 

しかし、あなたはこのようにそれを呼び出す必要があります。

let person = new Person(null, "George"); 
+0

あなたはすべてのパラメータをそこに設定しています。私が望むものだけを設定することができます。私が持っている最も近い解決策は、コンストラクタを使用しているので、正しい軌道に乗っているかもしれません。 – Langley

+1

実際、ファクトリを使ってアイテムを作成することはできますが、私が言ったように、 {名前: "Guy"}はうまく動作します。使用しているタイスクリプトのバージョンは何ですか? – toskv

+0

Hey toskv私はこのコメントを見ていませんでしたが、明らかにキャスティングはうまくいきました。私が欲しいものを達成するために間違ったクラスを宣言する方法でした。すべてのプロパティを初期化し、私が投稿したもののように見えるように変更し、あなたの受け入れられた答えを変更します。 – Langley

0

anyにJSON式をキャストします。 defaultを割り当てるための行は次のようになります。

default: Person = <any>{ name: "Guy" }; 
0

これはここに掲載他の答えを補完する別のオプション..です

あなたは

{ 
    name:"John" 
} 

初期化子いくつかのオブジェクトを持っていて、明示的にインスタンスをしたい場合クラスPersonのオブジェクトの初期値を保持したい場合は、クラスPersonが作成するデフォルト値をそのままにして、オブジェクト全体をクラスコンストラクタに渡すことで行うことができます:

var instance = new Person({name:"John"}); 

export class Person 
{ 
    id:number = 0; //or generate one 
    name:string = "unknown"; 
    constructor(opts:{id?:number; name?:string}){ 
     if(opts){ 
      this.id = opts.id || this.id; 
      this.name = opts.name || this.name; 
     } 
    } 
} 

例:

var people = [ 
    new Person(), 
    new Person({name:"John"}), 
    new Person({name:"James", id:10}), 
    new Person({id:20})]; 
関連する問題