2017-04-19 68 views
0

我正在創建一個處理數據庫中的對象的函數。我有兩個不同的數據結構,其中相同的屬性具有不同的名稱。我無法改變,所以我必須在JavaScript中處理它。
對象有其他區別,但這對此功能並不重要。
我想爲兩種不同類型的對象使用相同的功能。下面是示範我的問題的示例代碼:訪問打印腳本聯合類型中的不同屬性

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

您需要創建定義類型保護用戶,那麼你可以使用if語句並獲得正確的輸入。

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。 Item正確地轉換爲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; 
} 

根據打字稿文檔的正式方法是這樣的: 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; 
} 

或兩次,你」最好寫@Dary建議的類型後衛。

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通常會停止抱怨。不過,我會建議添加評論。