Experimenting with the upcoming TypeScript 4.1's template literal types, I tried to define a generic type that can check property paths.
Until TS 4.1, there was no possible way to type an expression such as 'foo.bar.baz', and you would have to settle for string. Now, with template literal types, I want to be able to type these property paths, and use them for things such as MongoDB queries and projection objects. For example:
db.someCollection.find({ 'foo.bar.baz': { $exists: true } });
This is the type that I came up with:
type PropsPath<T> =
T extends object
? T extends any[]
? number
: {
[P in keyof T]: P | `${P}.${PropsPath<T[P]>}`
}[keyof T]
: '';
Sadly, this type is considered "excessively deep or possibly infinite" by TS compiler. Is there any way to redefine it in a way that doesn't throw an error?