更容易编写复杂语句的方式

时间:2017-05-24 13:31:12

标签: javascript angular if-statement

我正在为Angular项目编写用户定义的类型保护。

以下if陈述(由我的评论标记)效果非常好 - 但我无法帮助,但我认为有更可读的方式来编写它们。

以下首先检查传递给函数的Object是否具有所需的道具(如果没有,则提前退出)。

下一个(和第三个)if语句检查prop activity的值是否为String。

第二个和第四个if语句需要检查props 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;
}

编写整个函数的确可能有更好的可读方式吗?!

3 个答案:

答案 0 :(得分:2)

首先,每个值都不存储在任何地方。你可以直接退回支票:

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

如果在对象中没有列表的所有这些属性,则objHasPropertiesInTheList将为false。因此,如果没有所有属性,请在此处添加支票并执行所需操作。

然后这个:

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;
}

答案 1 :(得分: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;
}

答案 2 :(得分: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')        
    );
}