Skip to content

Instantly share code, notes, and snippets.

@dispix
Last active October 18, 2021 15:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dispix/bf48c122d082900bbc8bb27d7a3ff139 to your computer and use it in GitHub Desktop.
Save dispix/bf48c122d082900bbc8bb27d7a3ff139 to your computer and use it in GitHub Desktop.
Gives a strong typing to string accessors like `lodash/get`
// Extracts the type of a property deeply nested in an object
// Example: DeepProperty<'foo[0].bar', { foo: Array<{ bar: { baz: string } }> }> === { baz: string }
export type PropertyType<
TModel extends Record<string, any>,
TPath extends string
> = TPath extends keyof TModel
? TModel[TPath]
: TPath extends `${infer Key}.${infer RemainingPath}`
? Key extends keyof TModel
? PropertyType<TModel[Key], RemainingPath>
: TPath extends `${infer DeeperKey}[${number}].${infer DeeperPath}`
? DeeperKey extends keyof TModel
? TModel[DeeperKey] extends any[]
? PropertyType<TModel[DeeperKey][0], DeeperPath> | undefined
: never
: never
: never
: TPath extends `${infer Key}[${number}]`
? TPath extends `${infer DeeperKey}[${number}].${infer RemainingPath}`
? DeeperKey extends keyof TModel
? TModel[DeeperKey] extends any[]
? PropertyType<TModel[DeeperKey][0], RemainingPath> | undefined
: never
: never
: Key extends keyof TModel
? TModel[Key] extends any[]
? TModel[Key][0] | undefined
: never
: never
: never;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment