必要なバージョン
今回の内容を実行するにはTypeScriptの4.1.2以降が必要です
型の変換等に関する定石はこちらを見てください
実現する内容
const value = { aaa: { bbb: { ccc: 'Test', ddd: 100 } } }
const ccc = getTreeValue(value, 'aaa/bbb/ccc') //型は自動的にstring
console.log(ccc) //Test
const ddd = getTreeValue(value, 'aaa/bbb/ddd') //型は自動的にnumber
console.log(ddd) //100
オブジェクトからスラッシュ区切りでデータを取り出し型推論させます。
この処理を行う方法は以降の内容を確認してください。
文字列リテラルを分解し、再帰的に型を取り出す処理
type PickTree<T, P> = P extends keyof T
? T[P]
: P extends `${infer R1}/${infer R2}`
? R1 extends keyof T
? PickTree<T[R1], R2>
: never
: never
文字列リテラルをテンプレートリテラルを経由し、inferで取り出して分解しています。後続の文字列は再帰で順次処理します。
オブジェクトの階層を辿ってデータを取り出す
const getTreeValue = <T extends { [_ in any]: any }, K extends string>(v: T, path: K) =>
path.split('/').reduce((a, b) => a[b], v) as TreePick<T, K>
こちらは実処理になります。文字列を分解して順番に内容を展開します。そして先ほど作ったTreePickで戻り値の型を決めます。
まとめ
TypeScriptはバージョンが進むにつれて、今まで出来なかった事が実現可能になっていきます。
夢が広がります。