Skip to content

Instantly share code, notes, and snippets.

@productdevbook
Created June 4, 2022 16:34
Show Gist options
  • Save productdevbook/fab2c5dca4b920afc886d3eabf83dc8d to your computer and use it in GitHub Desktop.
Save productdevbook/fab2c5dca4b920afc886d3eabf83dc8d to your computer and use it in GitHub Desktop.
nested property full
type TerminalType =
| string
| number
| bigint
| boolean
| null
| undefined
| any[]
| Map<any, any>
| Set<any>
| Date
| RegExp
| ((...args: any) => any)
/**
* Deep nested keys of an interface with dot syntax
*
* @example
* type t = RecursiveKeyOf<{a: {b: {c: string}}> // => 'a' | 'a.b' | 'a.b.c'
*/
export type RecursiveKeyOf<
T,
Prefix extends string = never,
> = T extends TerminalType
? never
: {
[K in keyof T & string]: [Prefix] extends [never]
? K | RecursiveKeyOf<T[K], K>
: `${Prefix}.${K}` | RecursiveKeyOf<T[K], `${Prefix}.${K}`>;
}[keyof T & string]
/**
* Get the type of a nested property with dot syntax
*
* Basically the inverse of `RecursiveKeyOf`
*
* @example
* type t = DeepPropertyType<{a: {b: {c: string}}}, 'a.b.c'> // => string
*/
export type DeepPropertyType<
T,
P extends RecursiveKeyOf<T>,
> = P extends `${infer Prefix}.${infer Rest}`
? Prefix extends keyof T
? Rest extends RecursiveKeyOf<T[Prefix]>
? DeepPropertyType<T[Prefix], Rest>
: never
: never
: P extends keyof T
? T[P]
: never
export interface RootObject {
userNotFound: UserNotFound
cc: string
}
export interface UserNotFound {
test: string
new: cc
}
export interface cc {
new2: string
new3: string
}
const newData = (key: RecursiveKeyOf<RootObject>) => {
return 'a'
}
newData('userNotFound')
newData('cc')
newData('userNotFound.new')
newData('userNotFound.new.new2')
newData('userNotFound.new.new3')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment