2017-09-17 6 views
1

私はTypescriptの学習を始めましたが、既にC#開発者にとっては本当に奇妙な音で迷っています。有効なクラスインスタンスを返さないことを約束します

概要:Promise<WsIdSessionResponse>WsIdSessionResponseクラスの同じフィールドを持っていますが、それが有効なWsIdSessionResponseインスタンスではありません変数を返します。

export class WsIdSessionService { 
    constructor(private http: HttpClient) { } 

    doLoginAsync(user: string, pwd: string): Promise<WsIdSessionResponse> { 
     let params = new HttpParams(); 
     params = params.append('username', user); 
     params = params.append('password', pwd); 
     return this.http.get<WsIdSessionResponse>(this.apiUrl, {params: params}) 
      .toPromise()); 
    }; 

WsIdSessionResponseクラスは、このようなものです:私はこの(私は問題のために役に立たない何かを省略しました)私が書いていないJSONのWebサービスを消費するようなサービスを持っている

長い話

export class WsIdSessionResponse { 
    public status: number; 
    public username: string; 

    public isOk(): boolean { 
     return this.status == 1; 
    } 
} 

私はWsIdSessionServiceからデータを取得する際に問題が来る:

var idSvc = this.wsIdSession.doLoginAsync(user, pwd); 
var t = idSvc.then(info => { 
    if (t.isOk()) { 
     // Do something here 
    } 
} 

私はt.isOk()を実行すると、私はisOk()が関数ではないことを私に言ってエラーが出ます!
何ですか?機能ではない?はい、私のクラスにはその機能があります!

は、膨大な時間を無駄にした後、私は最終的に私はfalse結果として取得し、このコードここ

var idSvc = this.wsIdSession.doLoginAsync(user, pwd); 
var t = idSvc.then(info => { 
    console.warn(`info is valid: ${info instanceof WsIdSessionResponse}`); 
} 

をしようと考えた:そう返された変数は、私が必要とするクラスの同じフィールドを持っていますが、それは本当ではありませんクラスのインスタンスとその理由isOk()関数が有効ではありません!
これはどのように可能ですか?つまり、は、WsIdSessionResponseの有効なインスタンスを返す必要があります。最終的にはエラーです...間違っていますか?

完全な情報を提供するだけです。http.get<WsIdSessionResponse>は、単純なJSON文字列を返すURLからデータを取得します。

これは予期された動作ですか、何か間違っていますか?

+0

ユーザーはC#の背景とまったく同じ問題を抱えていたように見えます。 TSはコンパイル時に型エラーのJSです。 JSから期待されないオブジェクトに対する魔法の変換は行いません。 – estus

答えて

1

<WsIdSessionResponse>は、オブジェクトをWsIdSessionResponseのインスタンスにしません。これは、それがインスタンスであり、型エラーを抑制すると考えるために型定義システムを騙す。 TypeScriptはタイプセーフなJavaScriptであり、コンパイル時にはJavaScriptにすぎません。

newで明示的にWsIdSessionResponseのインスタンスが作成されない限り、オブジェクトはObjectのままであり、isOkメソッドはありません。

動作するようになっています方法は次のとおりです。

interface IWsIdSessionResponse { 
    status: number; 
    username: string; 
} 

class WsIdSessionResponse implements IWsIdSessionResponse { 
    public status: number; 
    public username: string; 

    public isOk(): boolean { 
     return this.status == 1; 
    } 
} 

... 

doLoginAsync(user: string, pwd: string): Promise<WsIdSessionResponse> { 
     ... 
     return this.http.get<IWsIdSessionResponse>(this.apiUrl, {params: params}) 
      .map(plainResponseObj => Object.assign(new WsIdSessionResponse, plainResponseObj)) 
      .toPromise()); 
    }; 
+0

ありがとうございました、私はすでに手作業でインスタンスを作成することで解決しましたが、それほどエレガントでない方法です。あなたはJSについて正しいですが、私はC#との違いを学ばなければなりません。私は頭痛の種がたくさんあると確信しています。 – Marco

+0

私が '.map(resp =>'を使用すると 'プロパティマップが型 'Observable ''に存在しないというエラーが出ます。 タイプを削除しても、 'http.get'を使用しても、私は' Observable ' – Marco

+1

の型に対して同じエラーを受け取ります。 Object.assignは、既存のクラスに対するハックのビットです。ここでの適切なパターンは、自己充填クラスのコンストラクタを持つことです( 'Item' here、https://stackoverflow.com/a/45847569/3731501参照)。 'は型 'Observable'には存在しません。ObservableはObservableの角4の規則的な問題です。使用している演算子ごとに' import' rxjs/add/operator/map''などを使用してください。 – estus

関連する問題