2017-12-20 7 views
1

次のインターフェイスは、JSON API応答を定義するために使用されます。
ステータスフィールドは、要求が成功したかどうかを示します。
データフィールドは、要求が成功したときにサーバーから返されるデータ(使用可能な場合のみ)を設定するために使用されます。
同様に、メッセージフィールドは、失敗した要求の際にエラーメッセージを設定するために使用されます。TypeScriptコンパイラ:Genericsを使用するときのコンパイラエラーを回避する方法

export interface IResponse<T> { 
    status: 'success' | 'fail'; 
    data?: T; 
    message?: string; 
} 

サーバーからいくつかの会社データを取得する次の機能があるとします。
応答にはデータまたは文字列のいずれかが含まれます。次のように私はこの関数を呼び出すしようとすると

search(keyword: string): Observable<IResponse<ICompany[]|string>> { 
    return this.searchCompany(keyword); 
} 

は、私はどちらかICompany []または文字列可能性がありデータとしてコンパイルエラーを取得します。

this.dataImportService.search('') 
     .subscribe(
     data => { 
     data.data[0].company_name // compile error 
     }, err => { 
     }); 

このコンパイルエラーを取り除くにはどうすればよいですか?

+0

あなたは 'data.data [0] .company_name'試すことはできますか? –

+0

@BunyaminCoskuner申し訳ありませんが、その "データ"部分を逃しました。私はdata.data [0] .xxxでコンパイラエラーを取得しています –

答えて

1

TypeScriptコンパイラは、data.dataのようなネストされたプロパティを扱うときにいくつかの問題があります。トリックは、一時変数const data = data.dataを使用することです。その場合、TypeScriptコンパイラは、typeof data === ...type guardが機能しています。すなわち、ユニオンタイプICompany[] | stringは、if (typeof data === ...)ブロック内のICompany[]またはstringに絞り込むことができます。

dataresponseに名前を変更(以下混乱する)、我々は持っている:

this.dataImportService.search('').subscribe(response => { 
    const data = response.data; // inferred type: ICompany[]|string 
    if (typeof data !== 'string' && data.length) { 
     const firstCompany = data[0]; // inferred type: ICompany 
     firstCompany.company_name; // OK 
    } 
}); 

Live in the TypeScript Playground

1

コンパイルエラーを取り除きたい場合は、 >を使用して型チェックを避けることができます。

this.dataImportService.search('') 
     .subscribe(
     (data: any) => { // <- here 
     data.data[0].company_name // compile error 
     }, err => { 
}); 

本当にあなたはそうしてはいけません。 Typescriptは、検索メソッドが文字列を返す場合、エラーが発生するか、少なくとも予期しない動作が発生することを警告します。

「hoho or whatever」と返すと、data.dataは 'hoho or whatever' data.data [0] = 'h'となります。 data.data [0] .company_nameは未定義です。

関連する問題