2017-04-19 10 views
0

データベースからオブジェクトを処理する関数を作成しています。私は同じプロパティが異なる名前を持つ2つの異なるデータ構造を持っています。私はそれを変更することはできませんので、私はそれをJavaScriptで処理する必要があります。
オブジェクトには相違点がありますが、この機能には重要ではありません。
2つの異なるタイプのオブジェクトに対して同じ機能を使用したいと考えています。ここに私の問題を示すサンプルコードがあります:タイプコピーユニオンタイプの異なるプロパティへのアクセス

interface TypeA { 
    itemName: string; 
} 

interface TypeB { 
    itemTitle: string; 
} 

function getItemName(item: TypeA | TypeB): string { 
    let name = ''; 

    if (item.hasOwnProperty('itemName')) { 
     name = item.itemName; 
    } else { 
     name = item.itemTitle; 
    } 

    return name; 
} 

もちろん、このコードが実行されます。しかし、両方のタイプが両方のプロパティを持っていないので、IDEはname = item.itemName;name = item.itemTitle;の両方の行をエラーとしてマークします(「プロパティは型に存在しません」)。

これを行うには適切なタイスクリプトの方法は何ですか?

答えて

2

正しいタイピングを得ることができます。

function isTypeA(value: TypeA | TypeB): value is TypeA { 
    return value.hasOwnProperty('itemName'); 
} 

次に、あなたのタイピングがはるかにきれい得ることができます。

function getItemName(item: TypeA | TypeB): string { 
    return isTypeA(item) ? item.itemName : item.itemTitle; 
} 

hereを、それをチェックアウト。アイテムはTypeAまたはTypeBのいずれかに正しくキャストされます。

1

のIntelliJは、この構文を受け付けます

function getItemName(item: TypeA): string; 
function getItemName(item: TypeB): string; 
function getItemName(item): string { 
    return item.hasOwnProperty('itemName') ? item.itemName : item.itemTitle; 
} 

typescriptですドキュメントに従って公式の方法はこれです:あなたは、あなたがif文を使用することができ、タイプ警備隊ユーザー定義を作成する必要が https://www.typescriptlang.org/docs/handbook/functions.html

1

あなたはあまりにも頻繁にこれをしない場合は、型アサーションを行うことができます。

if (item.hasOwnProperty('itemName')) { 
    name = (item as TypeA).itemName; 
} else { 
    name = (item as TypeB).itemTitle; 
} 

または

if (item.hasOwnProperty('itemName')) { 
    name = (<TypeA>item).itemName; 
} else { 
    name = (<TypeB>item).itemTitle; 
} 

を使用すると、これは一度か二度以上をチェックするために必要がある場合には」 @Darylが示唆しているように、型ガードを良く書く。

0

使用typeguards

interface TypeA { 
    itemName: string; 
} 

interface TypeB { 
    itemTitle: string; 
} 

function isTypeA(val: any): val is TypeA 
{ 
    return val.hasOwnProperty('itemName'); 
} 

function isTypeB(val: any): val is TypeB 
{ 
    return val.hasOwnProperty('itemTitle'); 
} 

function getItemName(item: TypeA | TypeB): string 
{ 
    let name = ''; 

    if (isTypeA(item)) 
    { 
     name = item.itemName; 
    } 
    else 
    { 
     name = item.itemTitle; 
    } 

    return name; 
} 
0

私は物事を複雑にしません。あなたのオブジェクトにどちらか一方のプロパティがあることが本当に分かっているなら、name = item['itemName'] || item['itemTitle']またはname = item.hasOwnProperty('itemName') ? item['itemName'] : item['itemTitle']で十分でしょう。

ドット表記ではなくブラケット表記を使用してプロパティにアクセスすると、通常、TypeScriptが不平を表示することに注意してください。私は、コメントを追加することをお勧めします。

関連する問題