I am in search of a type that can describe any path through an object starting from the top (root) properties all the way down to every leaf property in the form of a string array. The following are the key characteristics required:
- The object's structure is defined by an interface / type
- There should be only a single path at a time, with no forks
- The ability to stop at any level along the path
- Selection limited to direct children, not allowing selection of sibling or ancestor nodes in the next step
- If a property holds an array within the object, there should be an option to choose a specific array entry either using a predicate function or a numeric index, followed by continuing based on the type of array entries (assuming homogeneous arrays)
- Optional properties should be treated as required for type checking purposes
- Intellisense support providing correct suggestions for auto completion
- The type should perform efficiently even with large objects / types
The type does not necessarily have to be recursive; it could have a predetermined number of nested levels where typing works before defaulting to "any" for deeper levels.
Complex coding tricks are acceptable as long as they deliver the desired functionality.
An example for clarity:
// Interface for the predicate function used to pick an array element:
export type PredicateFunction<ArrayType> = (array: ArrayType, index?: number) => boolean;
interface State {
city: {
name: string;
inhabitants: {
firstname: string;
lastname: string;
}[],
districts: string[]
}
}
// Valid "paths"
const path1 = ['city'];
const path4 = ['city', 'name'];
const path2 = ['city', 'inhabitants'];
const path3 = ['city', 'inhabitants', 1];
const path3 = ['city', 'inhabitants', inhabitant => inhabitant.firstname === 'Max', 'lastname'];
// Invalid "paths"
const invalidPath1 = ['name'];
const invalidPath2 = ['city', 'inhabitants', 'firstname'];
const invalidPath3 = ['inhabitants', 1, 'firstname'];