2016-09-10 6 views
1

TypeScriptを使用してアプリケーションを作成しています。オブジェクトを取得するAPI呼び出しを行っています。例えば、私はこのような活字体Userオブジェクトがあります。JSONのTypescriptオブジェクト

export class User { 
    id : number; 
    name : string; 
    email : string; 
} 

そして、私のAPIが返す

{ 
    "id" : 3, 
    "name" : "Jonn", 
    "email" : "[email protected]" 
} 

を私はJSONがUserに変換します。私はこれを行うことができます別の記事を読んだ:

let user : User = <User> myJson; 

これは動作します。私はuser.nameのようなユーザーのプロパティにアクセスできますが、私の問題は、Userクラスがいくつかのメソッドを実装している場合、そのプロパティは利用できないということです。これが起こる

getUppercaseName() : string { 
    return this.name.toUppercase(); 
} 

Userクラスの中、私はこの持っている場合たとえば、 user.name戻りJohnしかしuser.getUppercaseName()戻りundefined

を何が起こっているの?

export interface User { 
    id : number; 
    name : string; 
    email : string; 
} 

コンパイラはあなたがクラスをこのようis becauseを使用して文句ないことを理由:これはまったく同じに動作しますようあなたは、インターフェイスとしてクラスを処理することをやっているこの

答えて

2

を解決する方法

TypeScriptの基本原則の1つは、値の形状に があることです。これは時々

read more about duck typing

または実施例との「ダックタイピング」と呼ばまたは 「構造的サブタイプ」である:私は満たすオブジェクトを渡すlogUserへの2回の呼び出しで

class User { 
    id: number; 
    name: string; 
    email: string; 

    constructor(id: number, name: string, email: string) { 
     this.id = id; 
     this.name = name; 
     this.email = email; 
    } 
} 

function logUser(user: User) { 
    console.log(`user id: ${ user.id }, name: ${ user.name }, email: ${ user.email }`); 
} 

logUser({ 
    id: 1, 
    name: "user 1", 
    email: "mailaddress" 
}); 

logUser(new User(2, "user 2", "anotheraddress")); 

Userクラスのインターフェイスです。

あなたが代わりにそれを満たすオブジェクトのそのクラスのインスタンスを持ちたいなら、あなたのような何かをする必要があります

new User(myJson.id, myJson.name, myJson.email); 

をそして、私の例のようにコンストラクタを持っている、または:

interface IUser { 
    id: number; 
    name: string; 
    email: string; 
} 

class User implements IUser { 
    id: number; 
    name: string; 
    email: string; 

    constructor(data: IUser) { 
     this.id = data.id; 
     this.name = data.name; 
     this.email = data.email; 
    } 
} 

... 
new User(myJson); 
+0

私は、jsonデータを特定のクラスインスタンスに変換する方法が問題だと思います。 そのようなものは(ユーザのコンストラクタがあると仮定して)動作するはずですが、ngIfで結果を使用するとエラーが表示されます 返すthis._http.get(this.urll) .map((res:Response)=> res .json()) .map(obj:any => {新しいユーザー(obj.number、obj.name、obj.email);}) – rook

+0

@rook 'map'を2回使用する必要はありません。 => {let json = res.json();新しいユーザを返します(json.id、json.name、json.email); }) '。どのようなエラーが出ますか? –

+0

はい、短くなっていますが、エラーは同じです: 'オブジェクト'タイプのサポートオブジェクト '[オブジェクトオブジェクト]'が見つかりません。 NgForは、配列などのIterablesへのバインドのみをサポートしています。 – rook

2

ほとんどNitzanは、この背後にある理論を説明したので、私はちょうど別のアプローチを提供します:

interface UserInfo { 
    id: number; 
    name: string; 
    email: string; 
} 

class User { 
    userInfo: UserInfo; 
    constructor(userInfo: UserInfo) { 
     this.userInfo = userInfo; 
    } 
    getUpperCaseName(): string { 
     return this.userInfo.name.toLocaleUpperCase(); 
    } 
} 

const json = { 
    id: 3, 
    name: "Jonn", 
    email: "[email protected]" 
} 

let user: User = new User(json); 
0

ユーザーが50以上のプロパティを持つ場合に問題があります...

Userオブジェクトにコンストラクタを追加して、jsonオブジェクトを拡張します。あなたのAJAXコールバックで

export class User { 
    constructor(jsonUser: any) 
    { 
     $.extend(this, jsonUser); 
    } 
    id : number; 
    name : string; 
    email : string; 
    getUpperCaseName() {...} 
} 

、あなたのJSONオブジェクトからユーザオブジェクトを作成します。

let receivedUser = new User(jsonUser); 
let userName = receivedUser.getUpperCaseName(); 

は、私はそのpostでソリューションを詳細に説明。

関連する問題