How to make a recursive tree-like tuple?
I have a function for recursively getting the value of an object's property:
function getValue(obj: object, ...keys: string[]): any
and here is what it does given an object:
const testObject = {
hello: {
world: "Hello world!",
user: "Hello user!"
},
first: {
second: 2
},
shallow: {
deep: true
}
}
console.log(getValue(testObject, "first")); // { second: 2 }
console.log(getValue(testObject, "hello", "world")); // Hello world!
console.log(getValue(testObject, "shallow", "deep")); // true
My goal is adding autocomplete into the function parameters:
function getValueTyped<T extends object>(obj: T, ...keys: TreeKeys<T>): any
Please note that this function should be able to work with any given object type!
and the concept is (with the same object as above):
getValueTyped<typeof testObject>(
testObject,
"hello", // This parameter shows as a union: ("hello" | "first" | "shallow")
"world" // IF the previous parameter is "hello", than this one is ("world" | "user")
);
getValueTyped<typeof testObject>(
testObject,
"first", // This parameter shows as a union: ("hello" | "first" | "shallow")
"second" // IF the previous parameter is "first", than this one is only "second"
);
While trying to solve this, I came up with a few things. The type of the keys
argument should be a tuple with generics, something like this:
type TreeKeys<T extends object, K extends keyof T = keyof T> = [
K, // The first property
...(K extends object ? TreeKeys<T[K], keyof T[K]> : [])
];
but it obviously didn't work. I think using infer
might help, but I am not sure in how to implement this or if this is even possible.
If this is still not possible but there is a proposal, I would like to take a look at it.
Any help would be appreciated!