/** * Adds dot at end of string. */ type DotExtendedString = `${T}.`; /** * Converts path string to a an array of the path. Acts like split('.') * * Example: PathArray<'path1.path2.path3'> --> ['path1', 'path2', 'path3'] */ type PathArray = DotExtendedString extends `${infer A}.${infer B}` ? (A extends '' ? [] : [A, ...PathArray]) : []; /** * Creates a nested record with the nesting of path of the strings in the array that ends with object K. * * Example: NestedRecord<'path1.path2', {last: number}> --> {path1: { path2: {last: number}}} */ type NestedRecord = Path extends [infer Next, ...infer Rest] ? {[P in Next]: NestedRecord} : K; /** * Gets type of K at Path. */ type DeepGet = _DeepGet>; type _DeepGet> = T extends [infer First, ...infer Rest] ? First extends keyof K ? _DeepGet : never : K; /** * Create nested object from a PathString. * * Example: PathRecord<'path1.path2', {last: number}> --> {path1: { path2: {last: number}}} */ type PathRecord = NestedRecord, K>; /** * Combines a record at Path with existing record of an object or creates it if it doesn't exist. * * Example: AssertRecord<{path1: {path2: {last: number}}}, 'path1.path2', {reallyLast: string}> --> {path1: {path2: {last: number; reallyLast: string}}} */ export type AssetRecord = PathRecord< Path, DeepGet extends never ? Asset : (DeepGet & Asset) >;