@regle/core 0.1.7 → 0.1.9

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.
package/dist/index.d.cts CHANGED
@@ -1,9 +1,12 @@
1
- import * as vue from 'vue';
2
- import { MaybeRef, Ref, ComputedRef, UnwrapNestedRefs } from 'vue';
1
+ import { MaybeRef, Ref, UnwrapRef, UnwrapNestedRefs, ComputedRef } from 'vue';
3
2
 
3
+ type Prettify<T> = T extends infer R ? {
4
+ [K in keyof R]: R[K];
5
+ } & {} : never;
4
6
  type Maybe<T = any> = T | null | undefined;
5
- type MaybeGetter<T, V = any> = T | ((value: Ref<V>, index: number) => T);
6
- type ExtractFromGetter<T extends MaybeGetter<any, any>> = T extends MaybeGetter<infer U, any> ? U : never;
7
+ type MaybeGetter<T, V = any, TAdd extends Record<string, any> = {}> = T | ((value: Ref<V>, index: number) => T & TAdd);
8
+ type Unwrap<T extends MaybeRef<Record<string, any>>> = T extends Ref ? UnwrapRef<T> : UnwrapNestedRefs<T>;
9
+ type ExtractFromGetter<T extends MaybeGetter<any, any, any>> = T extends MaybeGetter<infer U, any, any> ? U : never;
7
10
  type DeepMaybeRef<T extends Record<string, any>> = {
8
11
  [K in keyof T]: MaybeRef<T[K]>;
9
12
  };
@@ -11,6 +14,7 @@ type ExcludeByType<T, U> = {
11
14
  [K in keyof T as T[K] extends U ? never : K]: T[K] extends U ? never : T[K];
12
15
  };
13
16
  type NonPresentKeys<TSource extends Record<string, any>, Target extends Record<string, any>> = Omit<Target, keyof TSource>;
17
+ type NoInferLegacy<A extends any> = [A][A extends any ? 0 : never];
14
18
 
15
19
  type ArrayElement<T> = T extends Array<infer U> ? U : never;
16
20
 
@@ -51,6 +55,68 @@ Unfortunately, `Record<string, never>`, `Record<keyof any, never>` and `Record<n
51
55
  */
52
56
  type EmptyObject = {[emptyObjectSymbol]?: never};
53
57
 
58
+ /**
59
+ Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
60
+
61
+ Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
62
+
63
+ @example
64
+ ```
65
+ import type {UnionToIntersection} from 'type-fest';
66
+
67
+ type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
68
+
69
+ type Intersection = UnionToIntersection<Union>;
70
+ //=> {the(): void; great(arg: string): void; escape: boolean};
71
+ ```
72
+
73
+ A more applicable example which could make its way into your library code follows.
74
+
75
+ @example
76
+ ```
77
+ import type {UnionToIntersection} from 'type-fest';
78
+
79
+ class CommandOne {
80
+ commands: {
81
+ a1: () => undefined,
82
+ b1: () => undefined,
83
+ }
84
+ }
85
+
86
+ class CommandTwo {
87
+ commands: {
88
+ a2: (argA: string) => undefined,
89
+ b2: (argB: string) => undefined,
90
+ }
91
+ }
92
+
93
+ const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
94
+ type Union = typeof union;
95
+ //=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
96
+
97
+ type Intersection = UnionToIntersection<Union>;
98
+ //=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
99
+ ```
100
+
101
+ @category Type
102
+ */
103
+ type UnionToIntersection<Union> = (
104
+ // `extends unknown` is always going to be the case and is used to convert the
105
+ // `Union` into a [distributive conditional
106
+ // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
107
+ Union extends unknown
108
+ // The union type is used as the only argument to a function since the union
109
+ // of function arguments is an intersection.
110
+ ? (distributedUnion: Union) => void
111
+ // This won't happen.
112
+ : never
113
+ // Infer the `Intersection` type since TypeScript represents the positional
114
+ // arguments of unions of functions as an intersection of the union.
115
+ ) extends ((mergedIntersection: infer Intersection) => void)
116
+ // The `& Union` is to allow indexing by the resulting type
117
+ ? Intersection & Union
118
+ : never;
119
+
54
120
  interface RegleBehaviourOptions {
55
121
  /**
56
122
  * Only display error when calling `validateState()`
@@ -74,7 +140,7 @@ interface LocalRegleBehaviourOptions<TState extends Record<string, any>, TRules
74
140
  externalErrors?: MaybeRef<TExternal>;
75
141
  validationGroups?: (fields: RegleStatus<TState, TRules>['$fields']) => TValidationGroups;
76
142
  }
77
- type RegleValidationGroupEntry = RegleFieldStatus<any, any, any>;
143
+ type RegleValidationGroupEntry = RegleFieldStatus<any, any>;
78
144
  interface RegleValidationGroupOutput {
79
145
  $invalid: boolean;
80
146
  $error: boolean;
@@ -100,9 +166,13 @@ interface Regle<TState extends Record<string, any> = EmptyObject, TRules extends
100
166
  errors: RegleErrorTree<TRules, TExternal>;
101
167
  ready: ComputedRef<boolean>;
102
168
  resetAll: () => void;
103
- validateState: () => Promise<false | DeepSafeFormState<TState, TRules>>;
169
+ validateState: () => Promise<false | Prettify<DeepSafeFormState<TState, TRules>>>;
104
170
  state: Ref<TState>;
105
171
  }
172
+ type isDeepExact<T, U> = {
173
+ [K in keyof T]-?: CheckDeepExact<NonNullable<T[K]>, K extends keyof U ? NonNullable<U[K]> : never>;
174
+ }[keyof T] extends true ? true : false;
175
+ type CheckDeepExact<T, U> = [U] extends [never] ? false : T extends RegleCollectionRuleDecl ? U extends RegleCollectionRuleDecl ? isDeepExact<NonNullable<T['$each']>, UnionToIntersection<NonNullable<U['$each']>>> : T extends RegleRuleDecl ? true : T extends ReglePartialValidationTree<any> ? isDeepExact<T, U> : false : T extends RegleRuleDecl ? true : T extends ReglePartialValidationTree<any> ? isDeepExact<T, U> : false;
106
176
  type DeepReactiveState<T extends Record<string, any>> = {
107
177
  [K in keyof T]: MaybeRef<T[K]>;
108
178
  };
@@ -200,9 +270,9 @@ type RegleRuleDefinitionProcessor<TValue extends any = any, TParams extends any[
200
270
  type RegleRuleDefinitionWithMetadataProcessor<TValue extends any, TMetadata extends RegleRuleMetadataConsumer<any, any>, TReturn = any> = ((value: Maybe<TValue>, metadata: TMetadata) => TReturn) | TReturn;
201
271
  type RegleCollectionRuleDefinition<TValue = any[], TCustomRules extends Partial<AllRulesDeclarations> = Partial<AllRulesDeclarations>> = (RegleRuleDecl<NonNullable<TValue>, TCustomRules> & {
202
272
  $each: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>>;
203
- }) | {
273
+ }) | ({
204
274
  $each: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>>;
205
- };
275
+ } & FieldRegleBehaviourOptions);
206
276
 
207
277
  /**
208
278
  * @argument
@@ -300,7 +370,7 @@ type RegleValidationTree<TForm extends Record<string, any>, TCustomRules extends
300
370
  /**
301
371
  * @public
302
372
  */
303
- type RegleComputedRules<TForm extends MaybeRef<Record<string, any>>, TCustomRules extends Partial<AllRulesDeclarations> | Regle<any, any> = Partial<AllRulesDeclarations>, TState = TForm extends Ref<infer R> ? R : TForm, TCustom = TCustomRules extends Regle<any, infer R> ? R extends ReglePartialValidationTree<any, infer C> ? C : Partial<AllRulesDeclarations> : TCustomRules> = {
373
+ type RegleComputedRules<TForm extends MaybeRef<Record<string, any>> | DeepReactiveState<Record<string, any>>, TCustomRules extends Partial<AllRulesDeclarations> | Regle<any, any> = Partial<AllRulesDeclarations>, TState = Unwrap<TForm>, TCustom = TCustomRules extends Regle<any, infer R> ? R extends ReglePartialValidationTree<any, infer C> ? C : Partial<AllRulesDeclarations> : TCustomRules> = {
304
374
  [TKey in keyof TState]?: RegleFormPropertyType<TState[TKey], TCustom extends Partial<AllRulesDeclarations> ? TCustom : {}>;
305
375
  };
306
376
  /**
@@ -323,11 +393,11 @@ type RegleCollectionRuleDeclKeyProperty = {
323
393
  /**
324
394
  * @public
325
395
  */
326
- type RegleCollectionRuleDecl<TValue = any[], TCustomRules extends Partial<AllRulesDeclarations> = Partial<AllRulesDeclarations>> = (RegleRuleDecl<NonNullable<TValue>, TCustomRules> & {
327
- $each?: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules> & RegleCollectionRuleDeclKeyProperty, ArrayElement<TValue>>;
328
- }) | {
329
- $each?: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>>;
330
- };
396
+ type RegleCollectionRuleDecl<TValue = any[], TCustomRules extends Partial<AllRulesDeclarations> = Partial<AllRulesDeclarations>> = ({
397
+ $each?: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>, RegleCollectionRuleDeclKeyProperty>;
398
+ } & RegleRuleDecl<NonNullable<TValue>, TCustomRules>) | ({
399
+ $each?: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>, RegleCollectionRuleDeclKeyProperty>;
400
+ } & FieldRegleBehaviourOptions);
331
401
  /**
332
402
  * @public
333
403
  */
@@ -377,17 +447,17 @@ type RegleStatus<TState extends Record<string, any> = Record<string, any>, TRule
377
447
  /**
378
448
  * @public
379
449
  */
380
- type InferRegleStatusType<TRule extends RegleCollectionRuleDecl | RegleRuleDecl | ReglePartialValidationTree<any>, TState extends Record<PropertyKey, any> = any, TKey extends PropertyKey = string> = TRule extends RegleCollectionRuleDefinition<any, any> ? NonNullable<TState[TKey]> extends Array<Record<string, any> | any> ? ExtractFromGetter<TRule['$each']> extends RegleRuleDecl | ReglePartialValidationTree<any> ? RegleCollectionStatus<ExtractFromGetter<TRule['$each']>, TState[TKey], TRule> : never : RegleFieldStatus<TRule, TState, TKey> : TRule extends ReglePartialValidationTree<any> ? NonNullable<TState[TKey]> extends Array<any> ? RegleCommonStatus<TState[TKey]> : NonNullable<TState[TKey]> extends Record<PropertyKey, any> ? RegleStatus<TState[TKey], TRule> : RegleFieldStatus<TRule, TState, TKey> : RegleFieldStatus<TRule, TState, TKey>;
450
+ type InferRegleStatusType<TRule extends RegleCollectionRuleDecl | RegleRuleDecl | ReglePartialValidationTree<any>, TState extends Record<PropertyKey, any> = any, TKey extends PropertyKey = string> = TRule extends RegleCollectionRuleDefinition<any, any> ? NonNullable<TState[TKey]> extends Array<Record<string, any> | any> ? ExtractFromGetter<TRule['$each']> extends RegleRuleDecl | ReglePartialValidationTree<any> ? RegleCollectionStatus<TState[TKey], ExtractFromGetter<TRule['$each']>, TRule> : never : RegleFieldStatus<TState[TKey], TRule> : TRule extends ReglePartialValidationTree<any> ? NonNullable<TState[TKey]> extends Array<any> ? RegleCommonStatus<TState[TKey]> : NonNullable<TState[TKey]> extends Record<PropertyKey, any> ? RegleStatus<TState[TKey], TRule> : RegleFieldStatus<TState[TKey], TRule> : RegleFieldStatus<TState[TKey], TRule>;
381
451
  /**
382
452
  * @public
383
453
  */
384
- interface RegleFieldStatus<TRules extends RegleFormPropertyType<any, Partial<AllRulesDeclarations>> = Record<string, any>, TState extends Record<PropertyKey, any> = any, TKey extends PropertyKey = string> extends RegleCommonStatus<TState> {
385
- $value: UnwrapNestedRefs<TState[TKey]>;
454
+ interface RegleFieldStatus<TState extends any = unknown, TRules extends RegleFormPropertyType<any, Partial<AllRulesDeclarations>> = Record<string, any>> extends RegleCommonStatus<TState> {
455
+ $value: UnwrapNestedRefs<TState>;
386
456
  readonly $errors: string[];
387
457
  readonly $silentErrors: string[];
388
458
  readonly $externalErrors?: string[];
389
459
  readonly $rules: {
390
- readonly [TRuleKey in keyof Omit<TRules, '$each' | keyof FieldRegleBehaviourOptions>]: RegleRuleStatus<TState[TKey], TRules[TRuleKey] extends RegleRuleDefinition<any, infer TParams, any> ? TParams : [], TRules[TRuleKey] extends RegleRuleDefinition<any, any, any, infer TMetadata> ? TMetadata : TRules[TRuleKey] extends InlineRuleDeclaration<any, any[], infer TMetadata> ? TMetadata extends Promise<infer P> ? P : TMetadata : never>;
460
+ readonly [TRuleKey in keyof Omit<TRules, '$each' | keyof FieldRegleBehaviourOptions>]: RegleRuleStatus<TState, TRules[TRuleKey] extends RegleRuleDefinition<any, infer TParams, any> ? TParams : [], TRules[TRuleKey] extends RegleRuleDefinition<any, any, any, infer TMetadata> ? TMetadata : TRules[TRuleKey] extends InlineRuleDeclaration<any, any[], infer TMetadata> ? TMetadata extends Promise<infer P> ? P : TMetadata : never>;
391
461
  };
392
462
  }
393
463
  /**
@@ -429,9 +499,9 @@ type RegleRuleStatus<TValue = any, TParams extends any[] = any[], TMetadata exte
429
499
  /**
430
500
  * @public
431
501
  */
432
- interface RegleCollectionStatus<TRules extends RegleRuleDecl | ReglePartialValidationTree<any>, TState extends any[], TFieldRule extends RegleCollectionRuleDecl<any, any> = never> extends Omit<RegleFieldStatus<TRules, TState>, '$errors' | '$silentErrors'> {
502
+ interface RegleCollectionStatus<TState extends any[] = any[], TRules extends RegleRuleDecl | ReglePartialValidationTree<any> = Record<string, any>, TFieldRule extends RegleCollectionRuleDecl<any, any> = never> extends Omit<RegleFieldStatus<TState, TRules>, '$errors' | '$silentErrors'> {
433
503
  readonly $each: Array<InferRegleStatusType<NonNullable<TRules>, NonNullable<TState>, number>>;
434
- readonly $field: RegleFieldStatus<TFieldRule, TState>;
504
+ readonly $field: RegleFieldStatus<TState, TFieldRule>;
435
505
  readonly $errors: RegleErrorTree<TRules>;
436
506
  readonly $silentErrors: RegleErrorTree<TRules>;
437
507
  }
@@ -475,11 +545,21 @@ declare function createRule<TValue extends any, TParams extends any[], TReturn e
475
545
  */
476
546
  declare function unwrapRuleParameters<TParams extends any[]>(params: ParamDecl[]): TParams;
477
547
 
478
- declare const useRegle: <TState extends Record<string, any>, TRules extends ReglePartialValidationTree<TState, Partial<AllRulesDeclarations>>, TExternal extends RegleExternalErrorTree<TState>, TValidationGroups extends Record<string, RegleValidationGroupEntry[]>, TValid = keyof TRules extends keyof TState ? true : false>(state: MaybeRef<TState> | DeepReactiveState<TState>, rulesFactory: TValid extends true ? TRules | ComputedRef<TRules> | (() => TRules) : never, options?: (Partial<DeepMaybeRef<RegleBehaviourOptions>> & LocalRegleBehaviourOptions<TState, TRules, TExternal, TValidationGroups>) | undefined) => Regle<TState, TRules, TExternal, TValidationGroups>;
548
+ type useRegleFn<TCustomRules extends Partial<AllRulesDeclarations>> = <TState extends Record<string, any>, TRules extends ReglePartialValidationTree<Unwrap<TState>, Partial<AllRulesDeclarations> & TCustomRules> & TValid, TExternal extends RegleExternalErrorTree<Unwrap<TState>>, TValidationGroups extends Record<string, RegleValidationGroupEntry[]>, TValid = isDeepExact<NoInferLegacy<TRules>, ReglePartialValidationTree<Unwrap<TState>, Partial<AllRulesDeclarations> & TCustomRules>> extends true ? {} : never>(state: MaybeRef<TState> | DeepReactiveState<TState>, rulesFactory: TRules | (() => TRules) | ComputedRef<TRules>, options?: Partial<DeepMaybeRef<RegleBehaviourOptions>> & LocalRegleBehaviourOptions<Unwrap<TState>, TRules, TExternal, TValidationGroups>) => Regle<Unwrap<TState>, TRules, TExternal, TValidationGroups>;
549
+ declare const useRegle: useRegleFn<Partial<AllRulesDeclarations>>;
550
+
551
+ interface inferRulesFn<TCustomRules extends Partial<AllRulesDeclarations>> {
552
+ <TState extends Record<string, any>, TRules extends ReglePartialValidationTree<Unwrap<TState>, Partial<AllRulesDeclarations> & TCustomRules> & TValid, TValid = isDeepExact<NoInferLegacy<TRules>, ReglePartialValidationTree<Unwrap<TState>, Partial<AllRulesDeclarations> & TCustomRules>> extends true ? {} : never>(state: MaybeRef<TState> | DeepReactiveState<TState>, rulesFactory: TRules): typeof rulesFactory;
553
+ <TState extends unknown, TRules extends RegleRuleDecl>(state: MaybeRef<TState>, rulesFactory: TRules): typeof rulesFactory;
554
+ }
555
+ declare const inferRules: inferRulesFn<Partial<AllRulesDeclarations>>;
479
556
 
480
557
  declare function defineRegleConfig<TCustomRules extends Partial<AllRulesDeclarations>>({ rules, modifiers, }: {
481
558
  rules?: () => TCustomRules;
482
559
  modifiers?: RegleBehaviourOptions;
483
- }): <TState extends Record<string, any>, TRules extends ReglePartialValidationTree<TState, Partial<AllRulesDeclarations> & TCustomRules>, TExternal extends RegleExternalErrorTree<TState>, TValidationGroups extends Record<string, RegleValidationGroupEntry[]>, TValid = keyof TRules extends keyof TState ? true : false>(state: vue.MaybeRef<TState> | DeepReactiveState<TState>, rulesFactory: TValid extends true ? TRules | vue.ComputedRef<TRules> | (() => TRules) : never, options?: (Partial<DeepMaybeRef<RegleBehaviourOptions>> & LocalRegleBehaviourOptions<TState, TRules, TExternal, TValidationGroups>) | undefined) => Regle<TState, TRules, TExternal, TValidationGroups>;
560
+ }): {
561
+ useRegle: useRegleFn<TCustomRules>;
562
+ inferRules: inferRulesFn<TCustomRules>;
563
+ };
484
564
 
485
- export { type DeepMaybeRef, type FormRuleDeclaration, type InlineRuleDeclaration, InternalRuleType, type LocalRegleBehaviourOptions, type Maybe, type ParamDecl, type Regle, type RegleBehaviourOptions, type RegleCollectionErrors, type RegleCollectionRuleDecl, type RegleCollectionRuleDefinition, type RegleCollectionStatus, type RegleCommonStatus, type RegleComputedRules, type RegleErrorTree, type RegleExternalCollectionErrors, type RegleExternalErrorTree, type RegleExternalValidationErrors, type RegleExternalValidationErrorsReport, type RegleFieldStatus, type RegleFormPropertyType, type RegleInternalRuleDefs, type ReglePartialValidationTree, type RegleRuleCore, type RegleRuleDecl, type RegleRuleDefinition, type RegleRuleDefinitionProcessor, type RegleRuleDefinitionWithMetadataProcessor, type RegleRuleInit, type RegleRuleMetadataConsumer, type RegleRuleMetadataDefinition, type RegleRuleRaw, type RegleRuleStatus, type RegleRuleWithParamsDefinition, type RegleStatus, type RegleUniversalParams, type RegleValidationErrors, type RegleValidationGroupEntry, type RegleValidationGroupOutput, type RegleValidationTree, type UnwrapRegleUniversalParams, createRule, defineRegleConfig, unwrapRuleParameters, useRegle };
565
+ export { type DeepMaybeRef, type FormRuleDeclaration, type InlineRuleDeclaration, InternalRuleType, type LocalRegleBehaviourOptions, type Maybe, type ParamDecl, type Regle, type RegleBehaviourOptions, type RegleCollectionErrors, type RegleCollectionRuleDecl, type RegleCollectionRuleDefinition, type RegleCollectionStatus, type RegleCommonStatus, type RegleComputedRules, type RegleErrorTree, type RegleExternalCollectionErrors, type RegleExternalErrorTree, type RegleExternalValidationErrors, type RegleExternalValidationErrorsReport, type RegleFieldStatus, type RegleFormPropertyType, type RegleInternalRuleDefs, type ReglePartialValidationTree, type RegleRuleCore, type RegleRuleDecl, type RegleRuleDefinition, type RegleRuleDefinitionProcessor, type RegleRuleDefinitionWithMetadataProcessor, type RegleRuleInit, type RegleRuleMetadataConsumer, type RegleRuleMetadataDefinition, type RegleRuleRaw, type RegleRuleStatus, type RegleRuleWithParamsDefinition, type RegleStatus, type RegleUniversalParams, type RegleValidationErrors, type RegleValidationGroupEntry, type RegleValidationGroupOutput, type RegleValidationTree, type Unwrap, type UnwrapRegleUniversalParams, createRule, defineRegleConfig, inferRules, unwrapRuleParameters, useRegle };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,12 @@
1
- import * as vue from 'vue';
2
- import { MaybeRef, Ref, ComputedRef, UnwrapNestedRefs } from 'vue';
1
+ import { MaybeRef, Ref, UnwrapRef, UnwrapNestedRefs, ComputedRef } from 'vue';
3
2
 
3
+ type Prettify<T> = T extends infer R ? {
4
+ [K in keyof R]: R[K];
5
+ } & {} : never;
4
6
  type Maybe<T = any> = T | null | undefined;
5
- type MaybeGetter<T, V = any> = T | ((value: Ref<V>, index: number) => T);
6
- type ExtractFromGetter<T extends MaybeGetter<any, any>> = T extends MaybeGetter<infer U, any> ? U : never;
7
+ type MaybeGetter<T, V = any, TAdd extends Record<string, any> = {}> = T | ((value: Ref<V>, index: number) => T & TAdd);
8
+ type Unwrap<T extends MaybeRef<Record<string, any>>> = T extends Ref ? UnwrapRef<T> : UnwrapNestedRefs<T>;
9
+ type ExtractFromGetter<T extends MaybeGetter<any, any, any>> = T extends MaybeGetter<infer U, any, any> ? U : never;
7
10
  type DeepMaybeRef<T extends Record<string, any>> = {
8
11
  [K in keyof T]: MaybeRef<T[K]>;
9
12
  };
@@ -11,6 +14,7 @@ type ExcludeByType<T, U> = {
11
14
  [K in keyof T as T[K] extends U ? never : K]: T[K] extends U ? never : T[K];
12
15
  };
13
16
  type NonPresentKeys<TSource extends Record<string, any>, Target extends Record<string, any>> = Omit<Target, keyof TSource>;
17
+ type NoInferLegacy<A extends any> = [A][A extends any ? 0 : never];
14
18
 
15
19
  type ArrayElement<T> = T extends Array<infer U> ? U : never;
16
20
 
@@ -51,6 +55,68 @@ Unfortunately, `Record<string, never>`, `Record<keyof any, never>` and `Record<n
51
55
  */
52
56
  type EmptyObject = {[emptyObjectSymbol]?: never};
53
57
 
58
+ /**
59
+ Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
60
+
61
+ Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
62
+
63
+ @example
64
+ ```
65
+ import type {UnionToIntersection} from 'type-fest';
66
+
67
+ type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
68
+
69
+ type Intersection = UnionToIntersection<Union>;
70
+ //=> {the(): void; great(arg: string): void; escape: boolean};
71
+ ```
72
+
73
+ A more applicable example which could make its way into your library code follows.
74
+
75
+ @example
76
+ ```
77
+ import type {UnionToIntersection} from 'type-fest';
78
+
79
+ class CommandOne {
80
+ commands: {
81
+ a1: () => undefined,
82
+ b1: () => undefined,
83
+ }
84
+ }
85
+
86
+ class CommandTwo {
87
+ commands: {
88
+ a2: (argA: string) => undefined,
89
+ b2: (argB: string) => undefined,
90
+ }
91
+ }
92
+
93
+ const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
94
+ type Union = typeof union;
95
+ //=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
96
+
97
+ type Intersection = UnionToIntersection<Union>;
98
+ //=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
99
+ ```
100
+
101
+ @category Type
102
+ */
103
+ type UnionToIntersection<Union> = (
104
+ // `extends unknown` is always going to be the case and is used to convert the
105
+ // `Union` into a [distributive conditional
106
+ // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
107
+ Union extends unknown
108
+ // The union type is used as the only argument to a function since the union
109
+ // of function arguments is an intersection.
110
+ ? (distributedUnion: Union) => void
111
+ // This won't happen.
112
+ : never
113
+ // Infer the `Intersection` type since TypeScript represents the positional
114
+ // arguments of unions of functions as an intersection of the union.
115
+ ) extends ((mergedIntersection: infer Intersection) => void)
116
+ // The `& Union` is to allow indexing by the resulting type
117
+ ? Intersection & Union
118
+ : never;
119
+
54
120
  interface RegleBehaviourOptions {
55
121
  /**
56
122
  * Only display error when calling `validateState()`
@@ -74,7 +140,7 @@ interface LocalRegleBehaviourOptions<TState extends Record<string, any>, TRules
74
140
  externalErrors?: MaybeRef<TExternal>;
75
141
  validationGroups?: (fields: RegleStatus<TState, TRules>['$fields']) => TValidationGroups;
76
142
  }
77
- type RegleValidationGroupEntry = RegleFieldStatus<any, any, any>;
143
+ type RegleValidationGroupEntry = RegleFieldStatus<any, any>;
78
144
  interface RegleValidationGroupOutput {
79
145
  $invalid: boolean;
80
146
  $error: boolean;
@@ -100,9 +166,13 @@ interface Regle<TState extends Record<string, any> = EmptyObject, TRules extends
100
166
  errors: RegleErrorTree<TRules, TExternal>;
101
167
  ready: ComputedRef<boolean>;
102
168
  resetAll: () => void;
103
- validateState: () => Promise<false | DeepSafeFormState<TState, TRules>>;
169
+ validateState: () => Promise<false | Prettify<DeepSafeFormState<TState, TRules>>>;
104
170
  state: Ref<TState>;
105
171
  }
172
+ type isDeepExact<T, U> = {
173
+ [K in keyof T]-?: CheckDeepExact<NonNullable<T[K]>, K extends keyof U ? NonNullable<U[K]> : never>;
174
+ }[keyof T] extends true ? true : false;
175
+ type CheckDeepExact<T, U> = [U] extends [never] ? false : T extends RegleCollectionRuleDecl ? U extends RegleCollectionRuleDecl ? isDeepExact<NonNullable<T['$each']>, UnionToIntersection<NonNullable<U['$each']>>> : T extends RegleRuleDecl ? true : T extends ReglePartialValidationTree<any> ? isDeepExact<T, U> : false : T extends RegleRuleDecl ? true : T extends ReglePartialValidationTree<any> ? isDeepExact<T, U> : false;
106
176
  type DeepReactiveState<T extends Record<string, any>> = {
107
177
  [K in keyof T]: MaybeRef<T[K]>;
108
178
  };
@@ -200,9 +270,9 @@ type RegleRuleDefinitionProcessor<TValue extends any = any, TParams extends any[
200
270
  type RegleRuleDefinitionWithMetadataProcessor<TValue extends any, TMetadata extends RegleRuleMetadataConsumer<any, any>, TReturn = any> = ((value: Maybe<TValue>, metadata: TMetadata) => TReturn) | TReturn;
201
271
  type RegleCollectionRuleDefinition<TValue = any[], TCustomRules extends Partial<AllRulesDeclarations> = Partial<AllRulesDeclarations>> = (RegleRuleDecl<NonNullable<TValue>, TCustomRules> & {
202
272
  $each: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>>;
203
- }) | {
273
+ }) | ({
204
274
  $each: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>>;
205
- };
275
+ } & FieldRegleBehaviourOptions);
206
276
 
207
277
  /**
208
278
  * @argument
@@ -300,7 +370,7 @@ type RegleValidationTree<TForm extends Record<string, any>, TCustomRules extends
300
370
  /**
301
371
  * @public
302
372
  */
303
- type RegleComputedRules<TForm extends MaybeRef<Record<string, any>>, TCustomRules extends Partial<AllRulesDeclarations> | Regle<any, any> = Partial<AllRulesDeclarations>, TState = TForm extends Ref<infer R> ? R : TForm, TCustom = TCustomRules extends Regle<any, infer R> ? R extends ReglePartialValidationTree<any, infer C> ? C : Partial<AllRulesDeclarations> : TCustomRules> = {
373
+ type RegleComputedRules<TForm extends MaybeRef<Record<string, any>> | DeepReactiveState<Record<string, any>>, TCustomRules extends Partial<AllRulesDeclarations> | Regle<any, any> = Partial<AllRulesDeclarations>, TState = Unwrap<TForm>, TCustom = TCustomRules extends Regle<any, infer R> ? R extends ReglePartialValidationTree<any, infer C> ? C : Partial<AllRulesDeclarations> : TCustomRules> = {
304
374
  [TKey in keyof TState]?: RegleFormPropertyType<TState[TKey], TCustom extends Partial<AllRulesDeclarations> ? TCustom : {}>;
305
375
  };
306
376
  /**
@@ -323,11 +393,11 @@ type RegleCollectionRuleDeclKeyProperty = {
323
393
  /**
324
394
  * @public
325
395
  */
326
- type RegleCollectionRuleDecl<TValue = any[], TCustomRules extends Partial<AllRulesDeclarations> = Partial<AllRulesDeclarations>> = (RegleRuleDecl<NonNullable<TValue>, TCustomRules> & {
327
- $each?: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules> & RegleCollectionRuleDeclKeyProperty, ArrayElement<TValue>>;
328
- }) | {
329
- $each?: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>>;
330
- };
396
+ type RegleCollectionRuleDecl<TValue = any[], TCustomRules extends Partial<AllRulesDeclarations> = Partial<AllRulesDeclarations>> = ({
397
+ $each?: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>, RegleCollectionRuleDeclKeyProperty>;
398
+ } & RegleRuleDecl<NonNullable<TValue>, TCustomRules>) | ({
399
+ $each?: MaybeGetter<RegleFormPropertyType<ArrayElement<NonNullable<TValue>>, TCustomRules>, ArrayElement<TValue>, RegleCollectionRuleDeclKeyProperty>;
400
+ } & FieldRegleBehaviourOptions);
331
401
  /**
332
402
  * @public
333
403
  */
@@ -377,17 +447,17 @@ type RegleStatus<TState extends Record<string, any> = Record<string, any>, TRule
377
447
  /**
378
448
  * @public
379
449
  */
380
- type InferRegleStatusType<TRule extends RegleCollectionRuleDecl | RegleRuleDecl | ReglePartialValidationTree<any>, TState extends Record<PropertyKey, any> = any, TKey extends PropertyKey = string> = TRule extends RegleCollectionRuleDefinition<any, any> ? NonNullable<TState[TKey]> extends Array<Record<string, any> | any> ? ExtractFromGetter<TRule['$each']> extends RegleRuleDecl | ReglePartialValidationTree<any> ? RegleCollectionStatus<ExtractFromGetter<TRule['$each']>, TState[TKey], TRule> : never : RegleFieldStatus<TRule, TState, TKey> : TRule extends ReglePartialValidationTree<any> ? NonNullable<TState[TKey]> extends Array<any> ? RegleCommonStatus<TState[TKey]> : NonNullable<TState[TKey]> extends Record<PropertyKey, any> ? RegleStatus<TState[TKey], TRule> : RegleFieldStatus<TRule, TState, TKey> : RegleFieldStatus<TRule, TState, TKey>;
450
+ type InferRegleStatusType<TRule extends RegleCollectionRuleDecl | RegleRuleDecl | ReglePartialValidationTree<any>, TState extends Record<PropertyKey, any> = any, TKey extends PropertyKey = string> = TRule extends RegleCollectionRuleDefinition<any, any> ? NonNullable<TState[TKey]> extends Array<Record<string, any> | any> ? ExtractFromGetter<TRule['$each']> extends RegleRuleDecl | ReglePartialValidationTree<any> ? RegleCollectionStatus<TState[TKey], ExtractFromGetter<TRule['$each']>, TRule> : never : RegleFieldStatus<TState[TKey], TRule> : TRule extends ReglePartialValidationTree<any> ? NonNullable<TState[TKey]> extends Array<any> ? RegleCommonStatus<TState[TKey]> : NonNullable<TState[TKey]> extends Record<PropertyKey, any> ? RegleStatus<TState[TKey], TRule> : RegleFieldStatus<TState[TKey], TRule> : RegleFieldStatus<TState[TKey], TRule>;
381
451
  /**
382
452
  * @public
383
453
  */
384
- interface RegleFieldStatus<TRules extends RegleFormPropertyType<any, Partial<AllRulesDeclarations>> = Record<string, any>, TState extends Record<PropertyKey, any> = any, TKey extends PropertyKey = string> extends RegleCommonStatus<TState> {
385
- $value: UnwrapNestedRefs<TState[TKey]>;
454
+ interface RegleFieldStatus<TState extends any = unknown, TRules extends RegleFormPropertyType<any, Partial<AllRulesDeclarations>> = Record<string, any>> extends RegleCommonStatus<TState> {
455
+ $value: UnwrapNestedRefs<TState>;
386
456
  readonly $errors: string[];
387
457
  readonly $silentErrors: string[];
388
458
  readonly $externalErrors?: string[];
389
459
  readonly $rules: {
390
- readonly [TRuleKey in keyof Omit<TRules, '$each' | keyof FieldRegleBehaviourOptions>]: RegleRuleStatus<TState[TKey], TRules[TRuleKey] extends RegleRuleDefinition<any, infer TParams, any> ? TParams : [], TRules[TRuleKey] extends RegleRuleDefinition<any, any, any, infer TMetadata> ? TMetadata : TRules[TRuleKey] extends InlineRuleDeclaration<any, any[], infer TMetadata> ? TMetadata extends Promise<infer P> ? P : TMetadata : never>;
460
+ readonly [TRuleKey in keyof Omit<TRules, '$each' | keyof FieldRegleBehaviourOptions>]: RegleRuleStatus<TState, TRules[TRuleKey] extends RegleRuleDefinition<any, infer TParams, any> ? TParams : [], TRules[TRuleKey] extends RegleRuleDefinition<any, any, any, infer TMetadata> ? TMetadata : TRules[TRuleKey] extends InlineRuleDeclaration<any, any[], infer TMetadata> ? TMetadata extends Promise<infer P> ? P : TMetadata : never>;
391
461
  };
392
462
  }
393
463
  /**
@@ -429,9 +499,9 @@ type RegleRuleStatus<TValue = any, TParams extends any[] = any[], TMetadata exte
429
499
  /**
430
500
  * @public
431
501
  */
432
- interface RegleCollectionStatus<TRules extends RegleRuleDecl | ReglePartialValidationTree<any>, TState extends any[], TFieldRule extends RegleCollectionRuleDecl<any, any> = never> extends Omit<RegleFieldStatus<TRules, TState>, '$errors' | '$silentErrors'> {
502
+ interface RegleCollectionStatus<TState extends any[] = any[], TRules extends RegleRuleDecl | ReglePartialValidationTree<any> = Record<string, any>, TFieldRule extends RegleCollectionRuleDecl<any, any> = never> extends Omit<RegleFieldStatus<TState, TRules>, '$errors' | '$silentErrors'> {
433
503
  readonly $each: Array<InferRegleStatusType<NonNullable<TRules>, NonNullable<TState>, number>>;
434
- readonly $field: RegleFieldStatus<TFieldRule, TState>;
504
+ readonly $field: RegleFieldStatus<TState, TFieldRule>;
435
505
  readonly $errors: RegleErrorTree<TRules>;
436
506
  readonly $silentErrors: RegleErrorTree<TRules>;
437
507
  }
@@ -475,11 +545,21 @@ declare function createRule<TValue extends any, TParams extends any[], TReturn e
475
545
  */
476
546
  declare function unwrapRuleParameters<TParams extends any[]>(params: ParamDecl[]): TParams;
477
547
 
478
- declare const useRegle: <TState extends Record<string, any>, TRules extends ReglePartialValidationTree<TState, Partial<AllRulesDeclarations>>, TExternal extends RegleExternalErrorTree<TState>, TValidationGroups extends Record<string, RegleValidationGroupEntry[]>, TValid = keyof TRules extends keyof TState ? true : false>(state: MaybeRef<TState> | DeepReactiveState<TState>, rulesFactory: TValid extends true ? TRules | ComputedRef<TRules> | (() => TRules) : never, options?: (Partial<DeepMaybeRef<RegleBehaviourOptions>> & LocalRegleBehaviourOptions<TState, TRules, TExternal, TValidationGroups>) | undefined) => Regle<TState, TRules, TExternal, TValidationGroups>;
548
+ type useRegleFn<TCustomRules extends Partial<AllRulesDeclarations>> = <TState extends Record<string, any>, TRules extends ReglePartialValidationTree<Unwrap<TState>, Partial<AllRulesDeclarations> & TCustomRules> & TValid, TExternal extends RegleExternalErrorTree<Unwrap<TState>>, TValidationGroups extends Record<string, RegleValidationGroupEntry[]>, TValid = isDeepExact<NoInferLegacy<TRules>, ReglePartialValidationTree<Unwrap<TState>, Partial<AllRulesDeclarations> & TCustomRules>> extends true ? {} : never>(state: MaybeRef<TState> | DeepReactiveState<TState>, rulesFactory: TRules | (() => TRules) | ComputedRef<TRules>, options?: Partial<DeepMaybeRef<RegleBehaviourOptions>> & LocalRegleBehaviourOptions<Unwrap<TState>, TRules, TExternal, TValidationGroups>) => Regle<Unwrap<TState>, TRules, TExternal, TValidationGroups>;
549
+ declare const useRegle: useRegleFn<Partial<AllRulesDeclarations>>;
550
+
551
+ interface inferRulesFn<TCustomRules extends Partial<AllRulesDeclarations>> {
552
+ <TState extends Record<string, any>, TRules extends ReglePartialValidationTree<Unwrap<TState>, Partial<AllRulesDeclarations> & TCustomRules> & TValid, TValid = isDeepExact<NoInferLegacy<TRules>, ReglePartialValidationTree<Unwrap<TState>, Partial<AllRulesDeclarations> & TCustomRules>> extends true ? {} : never>(state: MaybeRef<TState> | DeepReactiveState<TState>, rulesFactory: TRules): typeof rulesFactory;
553
+ <TState extends unknown, TRules extends RegleRuleDecl>(state: MaybeRef<TState>, rulesFactory: TRules): typeof rulesFactory;
554
+ }
555
+ declare const inferRules: inferRulesFn<Partial<AllRulesDeclarations>>;
479
556
 
480
557
  declare function defineRegleConfig<TCustomRules extends Partial<AllRulesDeclarations>>({ rules, modifiers, }: {
481
558
  rules?: () => TCustomRules;
482
559
  modifiers?: RegleBehaviourOptions;
483
- }): <TState extends Record<string, any>, TRules extends ReglePartialValidationTree<TState, Partial<AllRulesDeclarations> & TCustomRules>, TExternal extends RegleExternalErrorTree<TState>, TValidationGroups extends Record<string, RegleValidationGroupEntry[]>, TValid = keyof TRules extends keyof TState ? true : false>(state: vue.MaybeRef<TState> | DeepReactiveState<TState>, rulesFactory: TValid extends true ? TRules | vue.ComputedRef<TRules> | (() => TRules) : never, options?: (Partial<DeepMaybeRef<RegleBehaviourOptions>> & LocalRegleBehaviourOptions<TState, TRules, TExternal, TValidationGroups>) | undefined) => Regle<TState, TRules, TExternal, TValidationGroups>;
560
+ }): {
561
+ useRegle: useRegleFn<TCustomRules>;
562
+ inferRules: inferRulesFn<TCustomRules>;
563
+ };
484
564
 
485
- export { type DeepMaybeRef, type FormRuleDeclaration, type InlineRuleDeclaration, InternalRuleType, type LocalRegleBehaviourOptions, type Maybe, type ParamDecl, type Regle, type RegleBehaviourOptions, type RegleCollectionErrors, type RegleCollectionRuleDecl, type RegleCollectionRuleDefinition, type RegleCollectionStatus, type RegleCommonStatus, type RegleComputedRules, type RegleErrorTree, type RegleExternalCollectionErrors, type RegleExternalErrorTree, type RegleExternalValidationErrors, type RegleExternalValidationErrorsReport, type RegleFieldStatus, type RegleFormPropertyType, type RegleInternalRuleDefs, type ReglePartialValidationTree, type RegleRuleCore, type RegleRuleDecl, type RegleRuleDefinition, type RegleRuleDefinitionProcessor, type RegleRuleDefinitionWithMetadataProcessor, type RegleRuleInit, type RegleRuleMetadataConsumer, type RegleRuleMetadataDefinition, type RegleRuleRaw, type RegleRuleStatus, type RegleRuleWithParamsDefinition, type RegleStatus, type RegleUniversalParams, type RegleValidationErrors, type RegleValidationGroupEntry, type RegleValidationGroupOutput, type RegleValidationTree, type UnwrapRegleUniversalParams, createRule, defineRegleConfig, unwrapRuleParameters, useRegle };
565
+ export { type DeepMaybeRef, type FormRuleDeclaration, type InlineRuleDeclaration, InternalRuleType, type LocalRegleBehaviourOptions, type Maybe, type ParamDecl, type Regle, type RegleBehaviourOptions, type RegleCollectionErrors, type RegleCollectionRuleDecl, type RegleCollectionRuleDefinition, type RegleCollectionStatus, type RegleCommonStatus, type RegleComputedRules, type RegleErrorTree, type RegleExternalCollectionErrors, type RegleExternalErrorTree, type RegleExternalValidationErrors, type RegleExternalValidationErrorsReport, type RegleFieldStatus, type RegleFormPropertyType, type RegleInternalRuleDefs, type ReglePartialValidationTree, type RegleRuleCore, type RegleRuleDecl, type RegleRuleDefinition, type RegleRuleDefinitionProcessor, type RegleRuleDefinitionWithMetadataProcessor, type RegleRuleInit, type RegleRuleMetadataConsumer, type RegleRuleMetadataDefinition, type RegleRuleRaw, type RegleRuleStatus, type RegleRuleWithParamsDefinition, type RegleStatus, type RegleUniversalParams, type RegleValidationErrors, type RegleValidationGroupEntry, type RegleValidationGroupOutput, type RegleValidationTree, type Unwrap, type UnwrapRegleUniversalParams, createRule, defineRegleConfig, inferRules, unwrapRuleParameters, useRegle };