多次元的なオブジェクトのプロパティ指定をパスのように取得したい
TypeScript
TypeScript により多次元のパスを型として抽出する例が Stack Overflow にあった。
サンプル
下記のような事例において値である def
ではなく
プロパティの指定を a.b.c
のような形で取得したい場合が時に時々発生するかもしれません
const multipleDimension = {
a: {
b: {
c: 'def'
}
}
};
console.log(multipleDimension.a.b.c); // def
Proxy を使用して高次元のアクセス
How to use javascript proxy for nested objects - Stack Overflow のネストしたオブジェクトへの操作の事例を応用し・・・
const tracer = {
// 経路格納用
route: [],
get(target, prop) {
if (target.base === target) {
// 根元で初期化
this.route = [];
}
if (/^toPath$/.test(prop)) {
return this.route;
} else {
// 経路を保持
this.route.push(prop);
// toPath を完結させるためのダミーオブジェクト
const nextTarget = target[prop] instanceof Object ? target[prop] : {};
return new Proxy(nextTarget, tracer);
}
},
};
/**
* @type { <T>(target: T; tracer: tracer) => T }
*/
const tracerProxyFactory = (target, tracer) => {
// 根元の比較対象を保持しておく
const baseTarget = {
...target,
get base() {
return this;
},
};
return new Proxy(baseTarget, tracer);
};
const multipleDimension = {
a: {
b: {
c: 'def',
},
},
abc: {
def: {
ghi: 'jkl',
},
},
};
const b = {
a: {
b: {
c: 'def',
},
},
abc: {
def: {
ghi: 'jkl',
},
},
};
const tracerProxy = tracerProxyFactory(multipleDimension, tracer);
const tp = tracerProxyFactory(b, tracer);
console.log('RESULT', tracerProxy.a.b.toPath); // ["a", "b"]
console.log('RESULT', tp.a.b.toPath); // ["a", "b"]
console.log('RESULT', tracerProxy.abc.def.ghi.toPath); // ["abc", "def", "ghi"]
// 未定義のものもうけつけてしまった・・・
console.log('RESULT', tracerProxy.a.b.c.d.e.f.g.toPath); // ["a", "b", "c", "e", "f"]
もう少しなんとかなりそうなものですが・・・とりあえずこれで