2017-05-24 36 views
1

我正在爲我的Angular項目編寫一個用戶定義的類型警衛。更多可讀寫複雜的方法如果聲明

以下if聲明(由我的評論標記)工作得非常好 - 但我不禁想到會有更可讀的方式來編寫它們。

下面首先檢查傳遞給該函數的Object是否具有所需的道具(如果沒有,則退出)。

下一個(和第三個)if語句檢查prop的值activity是一個String。

第二和第四if語句需要檢查道具createdAtupdatedAt的值不是一個字符串類型的,或者說它們是對象,他們有自己的道具.sv誰的值是字符串timestamp

import { GridMetadata } from './grid-metadata'; 

export function isGridMetadata(obj: any): obj is GridMetadata { 
    [ 'activity', 'createdAt', 'totalReps', 'updatedAt' ].every((prop) => { 
    if (obj.hasOwnProperty(prop) === false) return false; 
    }); 

    if (typeof obj.activity !== 'string') return false; 

    // TODO: Better way to write this? 
    if (typeof obj.createdAt === 'string') {} 
    else if (obj.createdAt.hasOwnProperty('.sv') && obj.createdAt['.sv'] === 'timestamp') {} 
    else return false; 

    if (typeof obj.totalReps !== 'number') return false; 

    // TODO: Better way to write this? 
    if (typeof obj.updatedAt === 'string') {} 
    else if (obj.updatedAt.hasOwnProperty('.sv') && obj.updatedAt['.sv'] === 'timestamp') {} 
    else return false; 

    return true; 
} 

確實有更好的更可讀的方式來編寫整個函數?!

+0

首先,你需要單獨的邏輯的情況下,那麼你可能想使用三元二進制的情況下(只有一個,如果有其他人),並使用開關的情況下對多個案例(多個IF),這方式您的代碼將非常可讀。只是想知道你爲什麼使用空語句? – ProllyGeek

+0

我認爲你對'every'語句有問題。 'return false'不會返回'isGridMetadata'函數,它只是返回傳遞給'every'的匿名函數。 –

回答

2

首先,每個值不存儲。你也可以直接返回檢查:

var objHasPropertiesInTheList = [ 'activity', 'createdAt', 'totalReps', 'updatedAt' ].every((prop) => { 
    return obj.hasOwnProperty(prop); 
    }); 

現在,如果該對象有沒有列表的所有這些特性objHasPropertiesInTheList將是錯誤的。因此,請在此處添加支票,並在沒有所有屬性的情況下執行所需操作。

那麼這樣的:

if (typeof obj.createdAt === 'string') {} 
    else if (obj.createdAt.hasOwnProperty('.sv') && obj.createdAt['.sv'] === 'timestamp') {} 
    else return false; 

可簡單:

if (typeof(obj.createdAt) !== 'string' && obj.createdAt['.sv'] !== 'timestamp') { 
    return false; 
} 

而同爲最後一個:

if (typeof(obj.updatedAt) !== 'string' && obj.updatedAt['.sv'] !== 'timestamp') { 
    return false; 
} 
0

如果我不犯錯誤:

if (typeof obj.activity !== 'string' || 
    (!typeof obj.createdAt === 'string' && !(obj.createdAt.hasOwnProperty('.sv') && obj.createdAt['.sv'] === 'timestamp') || 
    typeof obj.totalReps !== 'number' || 
    (!typeof obj.updatedAt === 'string' && !(obj.updatedAt.hasOwnProperty('.sv') && obj.updatedAt['.sv'] === 'timestamp')) { 
    return false; 
} else { 
    return true; 
} 
+0

道歉,如果我不正確,但我不明白這將如何工作。我需要在循環內檢查'obj.hasOwnProperty(prop)',否則'prop'是未定義的。如果我在一個循環中,那麼聲明肯定會返回'false',因爲即使符合'prop'的條件,其他三個屬性也不會存在,因此失敗了? –

+0

對不起,我誤讀了,讓我編輯我的答案 – trichetriche

+0

完成,現在應該沒關係 – trichetriche

0

我想重寫它的等價和更緊湊的方式是:

function validateDateProperty(obj, dateProp) { 
 
    const dateVal = obj[dateProp]; 
 
    return typeof dateVal === 'string' || (dateVal.hasOwnProperty('.sv') && dateVal['.sv'] === 'timestamp'); 
 
} 
 

 
export function isGridMetadata(obj : any) : obj is GridMetadata { 
 
    if !(['activity', 'createdAt', 'totalReps', 'updatedAt'].every(prop => obj.hasOwnProperty(prop))) { 
 
     return false; 
 
    } 
 
    return (
 
     typeof obj.activity === 'string' 
 
     && typeof obj.totalReps === 'number' 
 
     && validateDateProperty(obj, 'createdAt') 
 
     && validateDateProperty(obj, 'updatedAt')   
 
    ); 
 
}