@@ -21,35 +21,58 @@ export type Narrow<A> = Try<A, [], NarrowRaw<A>>
21
21
22
22
type IsAny < T > = 0 extends 1 & T ? true : false
23
23
24
- export type ArrayAccessor < TPrefix extends string > = `${TPrefix } [${number } ]`
24
+ export interface AnyDeepKeyAndValue {
25
+ key : string
26
+ value : any
27
+ }
28
+
29
+ export type ArrayAccessor < TParent extends AnyDeepKeyAndValue > =
30
+ `${TParent [ 'key' ] extends never ? '' : TParent [ 'key' ] } [${number } ]`
31
+
32
+ export interface ArrayDeepKeyAndValue <
33
+ in out TParent extends AnyDeepKeyAndValue ,
34
+ in out T extends ReadonlyArray < any > ,
35
+ > {
36
+ key : ArrayAccessor < TParent >
37
+ value : T [ number ] | Nullable < TParent [ 'value' ] >
38
+ }
25
39
26
- export type DeepRecordArrayUnion <
40
+ export type DeepKeyAndValueArray <
41
+ TParent extends AnyDeepKeyAndValue ,
27
42
T extends ReadonlyArray < any > ,
28
- TPrefix extends string ,
29
43
TAcc ,
30
- > = DeepRecordUnion <
31
- T [ number ] ,
32
- ArrayAccessor < TPrefix > ,
33
- TAcc | Record < ArrayAccessor < TPrefix > , T [ number ] >
44
+ > = DeepKeysAndValues <
45
+ NonNullable < T [ number ] > ,
46
+ ArrayDeepKeyAndValue < TParent , T > ,
47
+ TAcc | ArrayDeepKeyAndValue < TParent , T >
34
48
>
35
49
36
50
export type TupleAccessor <
37
- TPrefix extends string ,
38
- TKey ,
39
- > = `${TPrefix } [${TKey & string } ]`
51
+ TParent extends AnyDeepKeyAndValue ,
52
+ TKey extends string ,
53
+ > = `${TParent [ 'key' ] extends never ? '' : TParent [ 'key' ] } [${TKey } ]`
54
+
55
+ export interface TupleDeepKeyAndValue <
56
+ in out TParent extends AnyDeepKeyAndValue ,
57
+ in out T ,
58
+ in out TKey extends AllTupleKeys < T > ,
59
+ > {
60
+ key : TupleAccessor < TParent , TKey >
61
+ value : T [ TKey ] | Nullable < TParent [ 'value' ] >
62
+ }
40
63
41
64
export type AllTupleKeys < T > = T extends any ? keyof T & `${number } ` : never
42
65
43
- export type DeepRecordTupleUnion <
66
+ export type DeepKeyAndValueTuple <
67
+ TParent extends AnyDeepKeyAndValue ,
44
68
T extends ReadonlyArray < any > ,
45
- TPrefix extends string ,
46
69
TAcc ,
47
70
TAllKeys extends AllTupleKeys < T > = AllTupleKeys < T > ,
48
71
> = TAllKeys extends any
49
- ? DeepRecordUnion <
50
- T [ TAllKeys ] ,
51
- TupleAccessor < TPrefix , TAllKeys > ,
52
- TAcc | Record < TupleAccessor < TPrefix , TAllKeys > , T [ TAllKeys ] >
72
+ ? DeepKeysAndValues <
73
+ NonNullable < T [ TAllKeys ] > ,
74
+ TupleDeepKeyAndValue < TParent , T , TAllKeys > ,
75
+ TAcc | TupleDeepKeyAndValue < TParent , T , TAllKeys >
53
76
>
54
77
: never
55
78
@@ -58,53 +81,85 @@ export type AllObjectKeys<T> = T extends any
58
81
: never
59
82
60
83
export type ObjectAccessor <
61
- TPrefix extends string ,
84
+ TParent extends AnyDeepKeyAndValue ,
62
85
TKey extends string | number ,
63
- > = TPrefix extends '' ? `${TKey } ` : `${TPrefix } .${TKey } `
86
+ > = TParent [ 'key' ] extends never ? `${TKey } ` : `${TParent [ 'key' ] } .${TKey } `
87
+
88
+ export type Nullable < T > = T & ( undefined | null )
89
+
90
+ export interface ObjectDeepKeyAndValue <
91
+ in out TParent extends AnyDeepKeyAndValue ,
92
+ in out T ,
93
+ in out TKey extends AllObjectKeys < T > ,
94
+ > {
95
+ key : ObjectAccessor < TParent , TKey >
96
+ value : T [ TKey ] | Nullable < TParent [ 'value' ] >
97
+ }
64
98
65
- export type DeepRecordObjectUnion <
99
+ export type DeepKeyAndValueObject <
100
+ TParent extends AnyDeepKeyAndValue ,
66
101
T ,
67
- TPrefix extends string ,
68
102
TAcc ,
69
103
TAllKeys extends AllObjectKeys < T > = AllObjectKeys < T > ,
70
104
> = TAllKeys extends any
71
- ? DeepRecordUnion <
72
- T [ TAllKeys ] ,
73
- ObjectAccessor < TPrefix , TAllKeys > ,
74
- TAcc | Record < ObjectAccessor < TPrefix , TAllKeys > , T [ TAllKeys ] >
105
+ ? DeepKeysAndValues <
106
+ NonNullable < T [ TAllKeys ] > ,
107
+ ObjectDeepKeyAndValue < TParent , T , TAllKeys > ,
108
+ TAcc | ObjectDeepKeyAndValue < TParent , T , TAllKeys >
75
109
>
76
110
: never
77
111
78
- export type DeepRecordUnion < T , TPrefix extends string = '' , TAcc = never > =
112
+ export type UnknownAccessor < TParent extends AnyDeepKeyAndValue > =
113
+ TParent [ 'key' ] extends never ? string : `${TParent [ 'key' ] } .${string } `
114
+
115
+ export interface UnknownDeepKeyAndValue < TParent extends AnyDeepKeyAndValue > {
116
+ key : UnknownAccessor < TParent >
117
+ value : unknown
118
+ }
119
+
120
+ export type DeepKeyAndValueUnknown < TParent extends AnyDeepKeyAndValue > =
121
+ UnknownDeepKeyAndValue < TParent >
122
+
123
+ export type DeepKeysAndValues <
124
+ T ,
125
+ TParent extends AnyDeepKeyAndValue = never ,
126
+ TAcc = never ,
127
+ > =
79
128
IsAny < T > extends true
80
129
? T
81
130
: T extends string | number | boolean | bigint | Date
82
131
? TAcc
83
132
: T extends ReadonlyArray < any >
84
133
? number extends T [ 'length' ]
85
- ? DeepRecordArrayUnion < T , TPrefix , TAcc >
86
- : DeepRecordTupleUnion < T , TPrefix , TAcc >
87
- : T extends object
88
- ? DeepRecordObjectUnion < T , TPrefix , TAcc >
89
- : TAcc
134
+ ? DeepKeyAndValueArray < TParent , T , TAcc >
135
+ : DeepKeyAndValueTuple < TParent , T , TAcc >
136
+ : keyof T extends never
137
+ ? TAcc | DeepKeyAndValueUnknown < TParent >
138
+ : T extends object
139
+ ? DeepKeyAndValueObject < TParent , T , TAcc >
140
+ : TAcc
90
141
91
142
export type DeepRecord < T > = {
92
- [ TRecord in DeepRecordUnion < T > as keyof TRecord ] : TRecord [ keyof TRecord ]
143
+ [ TRecord in DeepKeysAndValues < T > extends AnyDeepKeyAndValue
144
+ ? DeepKeysAndValues < T >
145
+ : never as TRecord [ 'key' ] ] : TRecord [ 'value' ]
93
146
}
94
147
95
- type UnionKeys < T > = T extends any ? keyof T : never
96
-
97
148
/**
98
149
* The keys of an object or array, deeply nested.
99
150
*/
100
151
export type DeepKeys < T > = unknown extends T
101
152
? string
102
- : UnionKeys < DeepRecordUnion < T > > & string
153
+ : DeepKeysAndValues < T > extends AnyDeepKeyAndValue
154
+ ? DeepKeysAndValues < T > [ 'key' ]
155
+ : never
103
156
104
157
/**
105
158
* Infer the type of a deeply nested property within an object or an array.
106
159
*/
107
160
export type DeepValue < TValue , TAccessor > =
108
161
DeepRecord < TValue > extends infer TDeepRecord
109
- ? TDeepRecord [ TAccessor & keyof TDeepRecord ]
162
+ ? TAccessor extends keyof TDeepRecord
163
+ ? TDeepRecord [ TAccessor ]
164
+ : never
110
165
: never
0 commit comments