Using TypeScript 4.5 and the following code, I need to find the paths of the properties of the Detail
interface.
export interface Base {
[key: string]: boolean | Base;
}
interface Detail extends Base {
propertyA: boolean,
propertyB: boolean,
moduleC: {
propertyD: boolean,
propertyE: boolean,
}
}
I need to get a type with 'propertyA' | 'propertyB' | 'moduleC.propertyD' | 'moduleC.propertyE'
.
Generally, there are solutions already existent, for instance here: Typescript: deep keyof of a nested object
But: given that type Path<T> = ...
gives me the paths of all keys of type T and writing const bad: Path<Detail> = 'propertyXY'
I want TypeScript to warn me about the wrong path.
Available solutions find the paths and allow for things like syntax completion. However, all the solutions fail with the [key: string]: boolean | Base
part in warning about wrong paths and so far I was unable find out why or how to fix this. Example (based on the aforementioned link):
type Join<K, P> = K extends string | number ?
P extends string | number ?
`${K}${"" extends P ? "" : "."}${P}`
: never : never;
type Path<T, D extends number = 10> = [D] extends [never] ? never : T extends Base ?
{ [K in keyof T]-?: Join<K, Path<T[K], Prev[D]>> }[keyof T] : "";
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]]
const bad: Path<Detail> = 'moduleC.propertyXY' // there should be a warning here because propertyXY doesn't exist but there isn't
What is an implementation for Path
that allows TypeScript to find wrong (in Detail
not existing) paths?