/**
 * See the definition of `@types/lodash`.
 */
type GetIndexedField<T, K> = K extends keyof T ? T[K] : K extends `${number}` ? 'length' extends keyof T ? number extends T['length'] ? number extends keyof T ? T[number] : undefined : undefined : undefined : undefined;
type FieldWithPossiblyUndefined<T, Key> = Get<Exclude<T, undefined>, Key> | Extract<T, undefined>;
type IndexedFieldWithPossiblyUndefined<T, Key> = GetIndexedField<Exclude<T, undefined>, Key> | Extract<T, undefined>;
type Get<T, P> = P extends `${infer Left}.${infer Right}` ? Left extends keyof Exclude<T, undefined> ? FieldWithPossiblyUndefined<Exclude<T, undefined>[Left], Right> | Extract<T, undefined> : Left extends `${infer FieldKey}[${infer IndexKey}]` ? FieldKey extends keyof T ? FieldWithPossiblyUndefined<IndexedFieldWithPossiblyUndefined<T[FieldKey], IndexKey>, Right> : undefined : undefined : P extends keyof T ? T[P] : P extends `${infer FieldKey}[${infer IndexKey}]` ? FieldKey extends keyof T ? IndexedFieldWithPossiblyUndefined<T[FieldKey], IndexKey> : undefined : IndexedFieldWithPossiblyUndefined<T, P>;

export type { Get };
