例如,在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;
}
}
这是正确的方法吗?还是有更好的方法?
答案 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