Skip to content

Commit

Permalink
feat(types): move Flatten type into the module
Browse files Browse the repository at this point in the history
  • Loading branch information
drizzer14 committed Jun 26, 2024
1 parent 0f8fd38 commit 9cc1ae9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 36 deletions.
47 changes: 11 additions & 36 deletions src/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,21 @@
*/

import permutation2 from './permutation/permutation-2'

/**
* Recursively flattens object type to a union of its keys
* combined through dot-notation.
*/
export type Flatten<
Source extends Record<string, unknown> | any[],
> =
| keyof Source extends keyof any[]
? `${number}`
: (
| keyof Source
| keyof {
[
Key in keyof Source as
Key extends string
? Source[Key] extends Record<string, unknown>
? `${Key}.${Flatten<Source[Key]>}`
: Source[Key] extends any[]
? Source[Key] extends Array<any[]> | Record<string, unknown>[]
? `${Key}.${number}` | `${Key}.${number}.${Flatten<Source[Key][number]>}`
: `${Key}.${number}`
: Key
: never
] : never
}
)
import type { Flatten, Flattenable } from './types/flatten'

/**
* Gets the value type inside a nested object type `Source` by provided `Path`
* written in dot-notation.
*/
export type Get<
Source,
Source extends Flattenable,
Path extends string
> =
Source extends Record<string, unknown>
? Path extends `${infer Index extends number}.${infer Right}`
? Path extends `${number}.${infer Right}`
? Get<Source, Right>
: Path extends `${infer Left extends keyof Source}.${infer Right}`
// @ts-ignore
? Get<Exclude<Source[Left], undefined>, Right> | Extract<Source[Left], undefined>
: Path extends keyof Source
? Source[Path]
Expand All @@ -60,9 +35,9 @@ export type Get<
* written in dot-notation.
*/
export default function get<
Source extends Record<string, unknown> | any[],
Source extends Flattenable,
Path extends Flatten<Source>
>(
> (
path: Path
): (source: Source) => Get<Source, Path>

Expand All @@ -71,9 +46,9 @@ export default function get<
* written in dot-notation.
*/
export default function get<
Source extends Record<string, unknown> | any[],
Source extends Flattenable,
Path extends Flatten<Source>
>(
> (
source: Source,
path: Path
): Get<Source, Path>
Expand All @@ -82,12 +57,12 @@ export default function get<
* Gets the value inside a nested `source` object by provided `path`
* written in dot-notation.
*/
export default function get(...args: [any, any?]): any {
export default function get (...args: [any, any?]): any {
return permutation2(
<
Source extends Record<string, unknown> | any[],
Source extends Flattenable,
Path extends string
>(
> (
source: Source,
path: Path
): Get<Source, Path> => {
Expand Down
34 changes: 34 additions & 0 deletions src/types/flatten.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @module Types
*/

/**
* Type subjective to flattening.
*/
export type Flattenable = Record<string, unknown> | any[]

/**
* Recursively flattens object type to a union of its keys
* combined through dot-notation.
*/
export type Flatten<
Source extends Record<string, unknown> | any[],
> = keyof Source extends keyof any[]
? `${number}`
: (
| keyof Source
| keyof {
[
Key in keyof Source as
Key extends string
? Source[Key] extends Record<string, unknown>
? `${Key}.${Flatten<Source[Key]>}`
: Source[Key] extends any[]
? Source[Key] extends Array<any[]> | Record<string, unknown>[]
? `${Key}.${number}` | `${Key}.${number}.${Flatten<Source[Key][number]>}`
: `${Key}.${number}`
: Key
: never
] : never
}
)
1 change: 1 addition & 0 deletions src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export type { Tuple } from './tuple'
export type { Effect } from './effect'
export type { Gradual } from './gradual'
export type { Unshift } from './unshift'
export type { Flatten } from './flatten'
export type { UnaryFunction, VariadicFunction } from './function'

0 comments on commit 9cc1ae9

Please sign in to comment.