[[Index]][]
import {A, L, O} from 'ts-toolbelt'
// Get a property in an object `o` at any depth with `path`
// `A.Cast<P, O.ValidPath<O, P>>` makes sure `path` is valid
const getAt = <
O extends object,
P extends L.List<A.Index>
>(o: O, path: A.Cast<P, O.ValidPath<O, P>>): O.Path<O, P> => {
let valueAt = o
for (const p of path)
valueAt = valueAt[p]
return valueAt as any
}
const test0 = getAt({a: {b: {c: 1}}}, ['a', 'b'] as const) // {c: number}
const test1 = getAt({a: {b: {c: 1}}} as const, ['a', 'b'] as const) // {c: 1}
const test2 = getAt({a: {b: {c: 1}}}, ['x'] as const) // error
Replaces invalid parts of a path with
never