Skip to content

Commit 4fd3d26

Browse files
committed
fix: optimize types for strict traverse
1 parent 994cef6 commit 4fd3d26

1 file changed

Lines changed: 22 additions & 19 deletions

File tree

src/traverse.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { VisitorMember, ValidatorFromType, ShapedValidator, OfValidator } from './type-utils';
2-
import { ObjectKeys, isPlainObject, normalizeResult, shouldAddToResult, toObj } from './utils';
2+
import { ObjectKeys, isPlainObject, shouldAddToResult, toObj } from './utils';
33
import { $boolean, $list, $listof, $number, $record, $recordof, $string } from './constants';
44
import {
55
Validator,
@@ -10,6 +10,10 @@ import {
1010
ListofValidator,
1111
} from './validatorTypes';
1212

13+
function normalizeResult(result: Record<string, any>) {
14+
return ObjectKeys(result).length <= 0 ? null : result;
15+
}
16+
1317
export type Visitor = Partial<
1418
{
1519
[K in VisitorMember]: (Utils: {
@@ -21,35 +25,34 @@ export type Visitor = Partial<
2125
}
2226
>;
2327

24-
type VisitorExists<
25-
V extends Validator,
26-
Vi extends Visitor,
27-
Def,
28-
VKey extends VisitorMember
29-
> = Vi[V['type']] extends undefined
30-
? Def
31-
: ReturnType<NonNullable<Vi[V['type']]>> extends infer X | null | undefined
32-
? Def | X
28+
type VisitorExists<Vi extends Visitor, Def, VKey extends VisitorMember> = Vi[VKey] extends undefined
29+
? NonNullable<Def> | undefined
30+
: ReturnType<NonNullable<Vi[VKey]>> extends infer X | null | undefined
31+
? X extends {} | [] | null
32+
? NonNullable<Def> | undefined
33+
: NonNullable<Def> | NonNullable<X> | undefined
3334
: ReturnType<NonNullable<Vi[VKey]>>;
3435

3536
type InferVisitorResult<V extends Validator, Vi extends Visitor> = V extends RecordValidator<
3637
infer S
3738
>
38-
? VisitorExists<V, Vi, { [K in keyof S]?: NonNullable<InferVisitorResult<S[K], Vi>> }, 'record'>
39+
? VisitorExists<Vi, { [K in keyof S]?: NonNullable<InferVisitorResult<S[K], Vi>> }, 'record'>
3940
: V extends ListValidator<infer A>
40-
? VisitorExists<V, Vi, InferVisitorResult<A[number], Vi>[], 'list'>
41+
? VisitorExists<Vi, NonNullable<InferVisitorResult<A[number], Vi>>[], 'list'>
4142
: V extends ListofValidator<infer VV>
42-
? VisitorExists<V, Vi, InferVisitorResult<VV, Vi>[], 'listof'>
43+
? VisitorExists<Vi, NonNullable<InferVisitorResult<VV, Vi>>[], 'listof'>
4344
: V extends RecordofValidator<infer VV>
44-
? VisitorExists<V, Vi, { [key: string]: InferVisitorResult<VV, Vi> | undefined }, 'recordof'>
45-
: ReturnType<NonNullable<Vi[V['type']]>> extends null | undefined
46-
? never
45+
? VisitorExists<
46+
Vi,
47+
{ [key: string]: NonNullable<InferVisitorResult<VV, Vi>> | undefined },
48+
'recordof'
49+
>
50+
: Vi[V['type']] extends void
51+
? undefined
4752
: ReturnType<NonNullable<Vi[V['type']]>>;
4853

4954
export type TraverseResult<S extends Schema, V extends Visitor> = {
50-
[K in keyof S]: InferVisitorResult<S[K], V> extends null | undefined
51-
? never
52-
: InferVisitorResult<S[K], V>;
55+
[K in keyof S]: NonNullable<InferVisitorResult<S[K], V>>;
5356
};
5457

5558
function enterNode(

0 commit comments

Comments
 (0)