访问可选属性的属性

时间:2018-02-23 17:49:09

标签: javascript typescript

访问可选属性的属性总是很麻烦。想象一下以下对象test1(在TypeScript表示法中):

interface Test {
    a?: { b?: { c?: { d?: string } } };
}

const test1: Test = { a: { b: { c: { d: 'e' } } } };

必须处理每个属性的缺失,以便接收'e',如果它是为了避免错误,例如:

let result;
const test2: Test = { a: { b: {} } };

尝试直接访问属性d会引发错误,因为cundefined,显然没有属性d

result = test2.a.b.c.d // TypeError: undefined is not an object

因此必须手动检查每个属性:

let result;
if (test2 && test2.a && test2.a.b && test2.a.b.c && test2.a.b.c.d !== undefined) {
    result = test2.a.b.c.d;
}

针对此常见问题的最短最佳实践解决方案是什么?

try/catch块可能有效,但似乎不够短。将test2.a.b.c.d作为函数参数传递给处理错误的函数似乎也不起作用,因为它会在输入函数之前抛出错误。

2 个答案:

答案 0 :(得分:0)

多年来,我一直在做很长的路。就在今天,我想出了一个使用回调函数的简短解决方案。这样,可以在外部函数内捕获执行错误。另外,如果找不到属性,可以传递第二个参数来设置值。

<强>使用

result = getOptionalProperty(()=>test2.a.b.c.d);

<强>实施

getOptionalProperty = <T, U>(callback: () => T | undefined, fallback?: U): T | U => {
    let result: T | undefined;

    try {
        result = callback();
    } catch (e) {
        result = undefined;
    }

    return (result === undefined) ? fallback : result;
}

答案 1 :(得分:0)

我为此目的使用此功能

Object.resolve = function(path, obj, error) {
      var res = path.split('.').reduce(function(prev, curr) {
          return prev ? prev[curr] : undefined
      }, obj || self);
    var error = (typeof error == "undefined" ? undefined:error);
      if(!res) 
         return error;
      return res;
}

这接受三个参数,第一个是您要访问的路径(例如:a.b.c.d),第二个是对象本身,第三个是如果找不到它应返回的内容。此函数检查路径中提到的属性,直到找到它,否则返回第三个参数。

请参阅以下示例:

Object.resolve = function(path, obj, error) {
      var res = path.split('.').reduce(function(prev, curr) {
          return prev ? prev[curr] : undefined
      }, obj || self);
    var error = (typeof error == "undefined" ? undefined:error);
      if(!res) 
         return error;
      return res;
}


var test = { a: { b: { c: { d: 'e' } } } };

console.log(Object.resolve("a.b.c.d", test, "Not present"));
console.log(Object.resolve("a.b.d", test, "Not present"));

PS,你可以轻松地在你的打字稿代码中这样做。我在Angular 5项目中使用它。