JS创建安全的get函数而不使用字符串

时间:2018-02-06 05:30:31

标签: javascript typescript

例如,在Lodash中,有get函数可以执行此操作:

_.get(object, 'a[0].b.c');
// => 3

_.get(object, ['a', '0', 'b', 'c']);
// => 3

_.get(object, 'a.b.c', 'default');

我对这种方法的问题是,当我使用打字稿时,它并不能保护我免受错别字的侵害。我试图创建一个类似的功能,而不传递字符串。

const obj = {a: {b: {c: {}}}, b: {}};

const a = get(obj, obj => obj.a.b.c.d.g, 'defaultValue');


function get(obj: T, getFn, defaultValue) {
  try {
    return getFn(obj);
  } catch(err) {
    return defaultValue;
  }
}

这是正确的方法吗?还是有更好的方法?

2 个答案:

答案 0 :(得分:2)

如果obj的结构与

相似,那么您当前的代码会失败
{a: {b: {c: { d: {} }}}, b: {}}

在这种情况下,您的代码将返回undefined。您还需要在try块中返回默认值,如下所示:

const obj = {a: {b: {c: { d: {} }}}, b: {}};

const a = get(obj, obj => obj.a.b.c.d.g, 'defaultValue');


function get(obj: T, getFn, defaultValue) {
  try {
    let val = getFn(obj);  
    if(val === null || val === undefined) { // SEE HERE
      return defaultValue;
    }
    return val;
  } catch(err) {
    return defaultValue;
  }
}

答案 1 :(得分:1)

根据您想要使用该功能的安全程度,我还会指定getFn的类型并将defaultValue约束为与结果og getFn

const obj = { a: { b: { c: { d: { g: '1' }} } }, b: {} };

function get<T, TResult>(obj: T, getFn: (o: T) => TResult, defaultValue: TResult) {
    try {
        let result =  getFn(obj);
        return result == undefined ? defaultValue : result;
    } catch (err) {
        return defaultValue;
    }
}


const aa = get(obj, obj => obj.a.b.c.d.g, 'defaultValue');
get({ x: 0 }, o => o.x, 'defaultValue'); // Compiler Error, x is number, default is string
get({ x: 0 }, o => o.x, 0); // Ok, same result  type
get({ x: { y : 1} }, o => o.x.yy, 0); // Compiler Error, Catches property typos as well