@effect-app/infra 2.16.6 → 2.16.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,7 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { expectTypeOf } from "@effect/vitest"
1
3
  import type { FieldValues } from "../fields.js"
2
- import type { BrowserNativeObject, Primitive } from "../utils.js"
4
+ import type { BrowserNativeObject, Equals, IsLiteral, IsNever, Primitive } from "../utils.js"
3
5
 
4
6
  import type { ArrayKey, IsTuple, TupleKeys } from "./common.js"
5
7
 
@@ -33,39 +35,6 @@ export type Path<T> = T extends ReadonlyArray<infer V> ? IsTuple<T> extends true
33
35
  */
34
36
  export type FieldPath<TFieldValues extends FieldValues> = Path<TFieldValues>
35
37
 
36
- /**
37
- * Helper type for recursively constructing paths through a type.
38
- * See {@link ArrayPath}
39
- */
40
- type ArrayPathImpl<K extends string | number, V> = V extends
41
- | Primitive
42
- | BrowserNativeObject ? never
43
- : V extends ReadonlyArray<infer U> ? U extends Primitive | BrowserNativeObject ? never
44
- : `${K}` | `${K}.${ArrayPath<V>}`
45
- : `${K}.${ArrayPath<V>}`
46
-
47
- /**
48
- * Type which eagerly collects all paths through a type which point to an array
49
- * type.
50
- * @typeParam T - type which should be introspected
51
- * @example
52
- * ```
53
- * Path<{foo: {bar: string[], baz: number[]}}> = 'foo.bar' | 'foo.baz'
54
- * ```
55
- */
56
- export type ArrayPath<T> = T extends ReadonlyArray<infer V> ? IsTuple<T> extends true ? {
57
- [K in TupleKeys<T>]-?: ArrayPathImpl<K & string, T[K]>
58
- }[TupleKeys<T>]
59
- : ArrayPathImpl<ArrayKey, V>
60
- : {
61
- [K in keyof T]-?: ArrayPathImpl<K & string, T[K]>
62
- }[keyof T]
63
-
64
- /**
65
- * See {@link ArrayPath}
66
- */
67
- export type FieldArrayPath<TFieldValues extends FieldValues> = ArrayPath<TFieldValues>
68
-
69
38
  /**
70
39
  * Type to evaluate the type which the given path points to.
71
40
  * @typeParam T - deeply nested type which is indexed by the path
@@ -76,17 +45,28 @@ export type FieldArrayPath<TFieldValues extends FieldValues> = ArrayPath<TFieldV
76
45
  * PathValue<[number, string], '1'> = string
77
46
  * ```
78
47
  */
79
- export type PathValue<T, P extends Path<T> | ArrayPath<T>> = T extends any
80
- ? P extends `${infer K}.${infer R}` ? K extends keyof T ? R extends Path<T[K]> ? PathValue<T[K], R>
81
- : never
82
- : K extends `${ArrayKey}` ? T extends ReadonlyArray<infer V> ? PathValue<V, R & Path<V>>
83
- : never
84
- : never
85
- : P extends keyof T ? T[P]
86
- : P extends `${ArrayKey}` ? T extends ReadonlyArray<infer V> ? V
48
+ /* dprint-ignore-start */
49
+ export type PathValue<T, P extends Path<T>> =
50
+ T extends any
51
+ ? P extends `${infer K}.${infer R}`
52
+ ? K extends keyof T
53
+ ? R extends Path<T[K]>
54
+ ? PathValue<T[K], R>
55
+ : never
56
+ : K extends `${ArrayKey}`
57
+ ? T extends ReadonlyArray<infer V>
58
+ ? PathValue<V, R & Path<V>>
59
+ : never
60
+ : never
61
+ : P extends keyof T
62
+ ? T[P]
63
+ : P extends `${ArrayKey}`
64
+ ? T extends ReadonlyArray<infer V>
65
+ ? V
66
+ : never
67
+ : never
87
68
  : never
88
- : never
89
- : never
69
+ /* dprint-ignore-end */
90
70
 
91
71
  /**
92
72
  * See {@link PathValue}
@@ -96,13 +76,165 @@ export type FieldPathValue<
96
76
  TFieldPath extends FieldPath<TFieldValues>
97
77
  > = PathValue<TFieldValues, TFieldPath>
98
78
 
99
- /**
100
- * See {@link PathValue}
101
- */
102
- export type FieldArrayPathValue<
79
+ /* dprint-ignore-start */
80
+ export type SetPathValue<T, P extends Path<T>, X> =
81
+ T extends any
82
+ ? P extends `${infer K}.${infer R}`
83
+ ? K extends keyof T
84
+ ? R extends Path<T[K]>
85
+ ? { [_ in keyof T]: _ extends K ? SetPathValue<T[K], R, X> : T[_] }
86
+ : never
87
+ : K extends `${ArrayKey}`
88
+ ? T extends ReadonlyArray<infer V>
89
+ ? { [_ in keyof T]: SetPathValue<V, R & Path<V>, X> }
90
+ : never
91
+ : never
92
+ : P extends keyof T
93
+ ? { [_ in keyof T]: _ extends P ? X : T[_] }
94
+ : P extends `${ArrayKey}`
95
+ ? T extends ReadonlyArray<any>
96
+ ? { [_ in keyof T]: X }
97
+ : never
98
+ : never
99
+ : never
100
+ /* dprint-ignore-end */
101
+
102
+ export type SetFieldPathValue<
103
103
  TFieldValues extends FieldValues,
104
- TFieldArrayPath extends FieldArrayPath<TFieldValues>
105
- > = PathValue<TFieldValues, TFieldArrayPath>
104
+ TFieldPath extends FieldPath<TFieldValues>,
105
+ X
106
+ > = SetPathValue<TFieldValues, TFieldPath, X>
107
+
108
+ /* dprint-ignore-start */
109
+ export type RefinePathValue<T, P extends Path<T>, X extends string | number | boolean | null | bigint, Exclde extends boolean = false> =
110
+ T extends any
111
+ // recursive cases
112
+ ? P extends `${infer K}.${infer R}`
113
+ ? K extends keyof T
114
+ ? R extends Path<T[K]>
115
+ ? { [_ in keyof T]: _ extends K ? RefinePathValue<T[K], R, X, Exclde> : T[_] }
116
+ : never
117
+ : K extends `${ArrayKey}`
118
+ ? T extends ReadonlyArray<infer V>
119
+ ? { [_ in keyof T]: RefinePathValue<V, R & Path<V>, X, Exclde> }
120
+ : never
121
+ : never
122
+ // base cases
123
+ : P extends keyof T
124
+ ? X extends T[P]
125
+ ? ({ [_ in keyof T]: _ extends P
126
+ ? Equals<
127
+ Exclde,
128
+ true,
129
+ Exclude<T[_], X>,
130
+ IsLiteral<T[_], X, Equals<X, null, null, NonNullable<T[_]>>>
131
+ >
132
+ : T[_]
133
+ }) extends infer $T
134
+ ? Equals<IsNever<$T[P & keyof $T]>, true, never, $T>
135
+ : never
136
+ : Equals<Exclde, true, T, never>
137
+ : P extends `${ArrayKey}`
138
+ ? T extends ReadonlyArray<infer V>
139
+ ? X extends V
140
+ ? { [_ in keyof T]: Equals<
141
+ Exclde,
142
+ true,
143
+ Exclude<T[_], X>,
144
+ IsLiteral<T[_], X, Equals<X, null, null, NonNullable<T[_]>>>
145
+ > }
146
+ : never
147
+ : never
148
+ : never
149
+ : never
150
+ /* dprint-ignore-end */
151
+
152
+ export type RefineFieldPathValue<
153
+ TFieldValues extends FieldValues,
154
+ TFieldPath extends FieldPath<TFieldValues>,
155
+ X extends string | number | boolean | null | bigint,
156
+ Exclde extends boolean = false
157
+ > = RefinePathValue<TFieldValues, TFieldPath, X, Exclde>
158
+
159
+ export namespace RefinePathValueTests {
160
+ type test1 = RefineFieldPathValue<{ a: { b: "tag1"; v1: string } | { b: "tag2"; v2: number } }, "a.b", "tag1">
161
+ expectTypeOf<test1>().toEqualTypeOf<{ a: { b: "tag1"; v1: string } }>()
162
+
163
+ type test2 = RefineFieldPathValue<{ b: "tag1"; v1: string } | { b: "tag2"; v2: number }, "b", "tag1">
164
+ expectTypeOf<test2>().toEqualTypeOf<{ b: "tag1"; v1: string }>()
165
+
166
+ type test3 = RefineFieldPathValue<{ b: "tag1" | "tag2" }, "b", "tag1">
167
+ expectTypeOf<test3>().toEqualTypeOf<{ b: "tag1" }>()
168
+
169
+ type test4 = RefineFieldPathValue<{ b: ("tag1" | "tag2")[] }, `b.${number}`, "tag1">
170
+ expectTypeOf<test4>().toEqualTypeOf<{ b: "tag1"[] }>()
171
+
172
+ type test5 = RefineFieldPathValue<{ b: "tag1"; v1: unknown } | { b: "tag2"; v2: unknown }, "b", "tag1">
173
+ expectTypeOf<test5>().toEqualTypeOf<{ b: "tag1"; v1: unknown }>()
174
+
175
+ type test6 = RefineFieldPathValue<
176
+ { a: { b: "tag1"; v1: string } | { b: "tag2"; v2: number } } | { something: "else " },
177
+ "a.b",
178
+ "tag2"
179
+ >
180
+ expectTypeOf<test6>().toEqualTypeOf<{ a: { b: "tag2"; v2: number } }>()
181
+
182
+ type test7 = RefineFieldPathValue<{ b: string | null }, "b", "tag1">
183
+ expectTypeOf<test7>().toEqualTypeOf<{ b: string }>()
184
+
185
+ type test8 = RefineFieldPathValue<{ b: string | null }, "b", null>
186
+ expectTypeOf<test8>().toEqualTypeOf<{ b: null }>()
187
+
188
+ type test1E = RefineFieldPathValue<{ a: { b: "tag1"; v1: string } | { b: "tag2"; v2: number } }, "a.b", "tag1", true>
189
+ expectTypeOf<test1E>().toEqualTypeOf<{ a: { b: "tag2"; v2: number } }>()
190
+
191
+ type test2E = RefineFieldPathValue<{ b: "tag1"; v1: string } | { b: "tag2"; v2: number }, "b", "tag2", true>
192
+ expectTypeOf<test2E>().toEqualTypeOf<{ b: "tag1"; v1: string }>()
193
+
194
+ type test3E = RefineFieldPathValue<{ b: "tag1" | "tag2" | null }, "b", null, true>
195
+ expectTypeOf<test3E>().toEqualTypeOf<{ b: "tag1" | "tag2" }>()
196
+
197
+ type test4E = RefineFieldPathValue<{ b: ("tag1" | "tag2")[] }, `b.${number}`, "tag1", true>
198
+ expectTypeOf<test4E>().toEqualTypeOf<{ b: "tag2"[] }>()
199
+
200
+ type test5E = RefineFieldPathValue<{ b: "tag1"; v1: unknown } | { b: "tag2"; v2: unknown }, "b", "tag1", true>
201
+ expectTypeOf<test5E>().toEqualTypeOf<{ b: "tag2"; v2: unknown }>()
202
+
203
+ type test6E = RefineFieldPathValue<
204
+ { a: { b: "tag1"; v1: string } | { b: "tag2"; v2: number } } | { something: "else " },
205
+ "a.b",
206
+ "tag2",
207
+ true
208
+ >
209
+ expectTypeOf<test6E>().toEqualTypeOf<{ a: { b: "tag1"; v1: string } }>()
210
+ }
211
+
212
+ export namespace SetFieldPathValueTests {
213
+ type test1 = SetFieldPathValue<{ foo: { bar: string[] } }, `foo.bar`, boolean>
214
+ expectTypeOf<test1>().toEqualTypeOf<{ foo: { bar: boolean } }>()
215
+
216
+ type test1a = SetFieldPathValue<{ foo: { bar: string[]; baz: 12 } }, `foo.bar`, boolean>
217
+ expectTypeOf<test1a>().toEqualTypeOf<{ foo: { bar: boolean; baz: 12 } }>()
218
+
219
+ type test2 = SetFieldPathValue<{ foo: { bar: string[] } }, `foo.bar.${number}`, boolean>
220
+ expectTypeOf<test2>().toEqualTypeOf<{ foo: { bar: boolean[] } }>()
221
+
222
+ type test2a = SetFieldPathValue<{ foo: { bar: readonly string[]; baz: 3 }; ban: 123 }, `foo.bar.${number}`, boolean>
223
+ expectTypeOf<test2a>().toEqualTypeOf<{ foo: { bar: readonly boolean[]; baz: 3 }; ban: 123 }>()
224
+
225
+ type test2b = SetFieldPathValue<
226
+ { foo: { bar: readonly { a: 1; b: 2 }[]; baz: 3 }; ban: 123 },
227
+ `foo.bar.${number}.b`,
228
+ "b"
229
+ >
230
+ expectTypeOf<test2b>().toEqualTypeOf<{ foo: { bar: readonly { a: 1; b: "b" }[]; baz: 3 }; ban: 123 }>()
231
+
232
+ type test3 = SetFieldPathValue<{ foo: ["a", "b"] }, `foo.0`, boolean>
233
+ expectTypeOf<test3>().toEqualTypeOf<{ foo: [boolean, "b"] }>()
234
+
235
+ type test3a = SetFieldPathValue<{ foo: [{ a: 123 }, "b"] }, `foo.0.a`, boolean>
236
+ expectTypeOf<test3a>().toEqualTypeOf<{ foo: [{ a: boolean }, "b"] }>()
237
+ }
106
238
 
107
239
  /**
108
240
  * Type to evaluate the type which the given paths point to.
@@ -1,14 +1,4 @@
1
1
  /** Re-export public API */
2
2
 
3
3
  export type { PathString } from "./common.js"
4
- export type {
5
- ArrayPath,
6
- FieldArrayPath,
7
- FieldArrayPathValue,
8
- FieldPath,
9
- FieldPathByValue,
10
- FieldPathValue,
11
- FieldPathValues,
12
- Path,
13
- PathValue
14
- } from "./eager.js"
4
+ export type { FieldPath, FieldPathByValue, FieldPathValue, FieldPathValues, Path, PathValue } from "./eager.js"
@@ -104,3 +104,25 @@ export type Merge<A, B> = {
104
104
  : K extends keyof B ? B[K]
105
105
  : never
106
106
  }
107
+
108
+ export type Resolve<T> =
109
+ & {
110
+ [K in keyof T]: Resolve<T[K]>
111
+ }
112
+ & unknown
113
+
114
+ export type ResolveFirstLevel<T> =
115
+ & {
116
+ [K in keyof T]: T[K]
117
+ }
118
+ & unknown
119
+
120
+ export type Cast<T, U> = T extends U ? T : U
121
+
122
+ export type IsLiteral<T, True, False> = string extends T ? False : number extends T ? False : True
123
+
124
+ export type Extends<T, U, True, False> = T extends U ? True : False
125
+
126
+ export type IsEqual<T, U> = (<_>() => _ extends T ? 1 : 2) extends (<_>() => _ extends U ? 1 : 2) ? true : false
127
+
128
+ export type Equals<T, U, True, False> = IsEqual<T, U> extends true ? True : False