Skip to content

Instantly share code, notes, and snippets.

@JamesGelok
Created October 6, 2021 18:59
Show Gist options
  • Save JamesGelok/04816e6c338d08beb830c3f75aa40625 to your computer and use it in GitHub Desktop.
Save JamesGelok/04816e6c338d08beb830c3f75aa40625 to your computer and use it in GitHub Desktop.
FAILED to extend this to match natural indexing syntax better. Hopefully I can get back to this another time https://stackoverflow.com/questions/12787781/type-definition-in-object-literal-in-typescript
export type AllObjectPaths<TObj extends Readonly<UTIL.ExplicitObjectLiteral>> = TObj extends Record<
infer Key extends AllowedKeys ? AllowedKeys : never,
UTIL.ExplicitObjectLiteral
>
? {
// 1. Create an object literal type (`{}`) from `TObj`, where all the individual
// properties are mapped to a string type if the value is not an object
// or union of string types containing the current and descendant
// possibilities when it's an object type.
// Does this for every property in `TObj` that is a string or number
[TPropName in keyof TObj & AllowedKeys]: TPropName extends `${number}`
?
| `[${TPropName}]`
// 2. And return the property name concatenated with a `.` and
// all the return values of `AllObjectPaths<TValue>`
| `[${TPropName}]${AllObjectPaths<TObj[TPropName]>}`
: // 1. Return the current property name as a string
| `.${TPropName}`
// 2. And return the property name concatenated with a `.` and
// all the return values of `AllObjectPaths<TValue>`
| `.${TPropName}${AllObjectPaths<TObj[TPropName]>}`;
}[keyof TObj & AllowedKeys] // for every string or number property name // 2. Now flatten the object's property types to a final union type
: never;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment