Skip to content

Commit 297f168

Browse files
fix: tuple describe() method (#1947)
* Add tuple.describe() * Undo clone method change * Use types instead of innerType, use proper describe arg * Undo array changes * Update array spec * Update types and spec
1 parent f37a53f commit 297f168

File tree

5 files changed

+112
-6
lines changed

5 files changed

+112
-6
lines changed

src/array.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,23 @@ export function create<C extends Maybe<AnyObject> = AnyObject, T = any>(
3838
return new ArraySchema<T[] | undefined, C>(type as any);
3939
}
4040

41+
interface ArraySchemaSpec<TIn, TContext> extends SchemaSpec<any> {
42+
types?: ISchema<InnerType<TIn>, TContext>
43+
}
44+
4145
export default class ArraySchema<
4246
TIn extends any[] | null | undefined,
4347
TContext,
4448
TDefault = undefined,
4549
TFlags extends Flags = '',
4650
> extends Schema<TIn, TContext, TDefault, TFlags> {
51+
declare spec: ArraySchemaSpec<TIn, TContext>;
4752
readonly innerType?: ISchema<InnerType<TIn>, TContext>;
4853

4954
constructor(type?: ISchema<InnerType<TIn>, TContext>) {
5055
super({
5156
type: 'array',
57+
spec: { types: type } as ArraySchemaSpec<TIn, TContext>,
5258
check(v: any): v is NonNullable<TIn> {
5359
return Array.isArray(v);
5460
},
@@ -183,6 +189,11 @@ export default class ArraySchema<
183189
// @ts-expect-error readonly
184190
next.innerType = schema;
185191

192+
next.spec = {
193+
...next.spec,
194+
types: schema as ISchema<InnerType<TIn>, TContext>
195+
}
196+
186197
return next as any;
187198
}
188199

@@ -263,7 +274,7 @@ export default class ArraySchema<
263274
value: innerOptions.value[0],
264275
};
265276
}
266-
base.innerType = this.innerType.describe(options);
277+
base.innerType = this.innerType.describe(innerOptions);
267278
}
268279
return base;
269280
}

src/schema.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export interface SchemaRefDescription {
100100
}
101101

102102
export interface SchemaInnerTypeDescription extends SchemaDescription {
103-
innerType?: SchemaFieldDescription;
103+
innerType?: SchemaFieldDescription | SchemaFieldDescription[];
104104
}
105105

106106
export interface SchemaObjectDescription extends SchemaDescription {

src/tuple.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import type {
1111
UnsetFlag,
1212
Maybe,
1313
} from './util/types';
14-
import Schema, { RunTest, SchemaSpec } from './schema';
14+
import type { ResolveOptions } from './Condition';
15+
import Schema, {
16+
RunTest,
17+
SchemaInnerTypeDescription,
18+
SchemaSpec,
19+
} from './schema';
1520
import ValidationError from './ValidationError';
1621
import { tuple as tupleLocale } from './locale';
1722

@@ -148,6 +153,22 @@ export default class TupleSchema<
148153
);
149154
});
150155
}
156+
157+
describe(options?: ResolveOptions<TContext>) {
158+
let base = super.describe(options) as SchemaInnerTypeDescription;
159+
base.innerType = this.spec.types.map((schema, index) => {
160+
let innerOptions = options;
161+
if (innerOptions?.value) {
162+
innerOptions = {
163+
...innerOptions,
164+
parent: innerOptions.value,
165+
value: innerOptions.value[index],
166+
};
167+
}
168+
return schema.describe(innerOptions);
169+
});
170+
return base;
171+
}
151172
}
152173

153174
create.prototype = TupleSchema.prototype;

test/mixed.ts

+76-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
ref,
1010
Schema,
1111
string,
12+
tuple,
1213
ValidationError,
1314
} from '../src';
1415
import ObjectSchema from '../src/object';
@@ -965,6 +966,7 @@ describe('Mixed Types ', () => {
965966
is: 'entered',
966967
then: (s) => s.defined(),
967968
}),
969+
baz: tuple([string(), number()])
968970
});
969971
});
970972

@@ -976,7 +978,8 @@ describe('Mixed Types ', () => {
976978
default: {
977979
foo: undefined,
978980
bar: 'a',
979-
lazy: undefined
981+
lazy: undefined,
982+
baz: undefined,
980983
},
981984
nullable: false,
982985
optional: true,
@@ -1035,6 +1038,41 @@ describe('Mixed Types ', () => {
10351038
},
10361039
],
10371040
},
1041+
baz: {
1042+
type: 'tuple',
1043+
meta: undefined,
1044+
label: undefined,
1045+
default: undefined,
1046+
nullable: false,
1047+
optional: true,
1048+
tests: [],
1049+
oneOf: [],
1050+
notOneOf: [],
1051+
innerType: [
1052+
{
1053+
type: 'string',
1054+
meta: undefined,
1055+
label: undefined,
1056+
default: undefined,
1057+
nullable: false,
1058+
optional: true,
1059+
oneOf: [],
1060+
notOneOf: [],
1061+
tests: [],
1062+
},
1063+
{
1064+
type: 'number',
1065+
meta: undefined,
1066+
label: undefined,
1067+
default: undefined,
1068+
nullable: false,
1069+
optional: true,
1070+
oneOf: [],
1071+
notOneOf: [],
1072+
tests: [],
1073+
}
1074+
],
1075+
},
10381076
},
10391077
});
10401078
});
@@ -1047,7 +1085,8 @@ describe('Mixed Types ', () => {
10471085
default: {
10481086
foo: undefined,
10491087
bar: 'a',
1050-
lazy: undefined
1088+
lazy: undefined,
1089+
baz: undefined,
10511090
},
10521091
nullable: false,
10531092
optional: true,
@@ -1111,6 +1150,41 @@ describe('Mixed Types ', () => {
11111150
},
11121151
],
11131152
},
1153+
baz: {
1154+
type: 'tuple',
1155+
meta: undefined,
1156+
label: undefined,
1157+
default: undefined,
1158+
nullable: false,
1159+
optional: true,
1160+
tests: [],
1161+
oneOf: [],
1162+
notOneOf: [],
1163+
innerType: [
1164+
{
1165+
type: 'string',
1166+
meta: undefined,
1167+
label: undefined,
1168+
default: undefined,
1169+
nullable: false,
1170+
optional: true,
1171+
oneOf: [],
1172+
notOneOf: [],
1173+
tests: [],
1174+
},
1175+
{
1176+
type: 'number',
1177+
meta: undefined,
1178+
label: undefined,
1179+
default: undefined,
1180+
nullable: false,
1181+
optional: true,
1182+
oneOf: [],
1183+
notOneOf: [],
1184+
tests: [],
1185+
}
1186+
],
1187+
},
11141188
},
11151189
});
11161190
});

test/tuple.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ describe('Array types', () => {
9191
);
9292
});
9393

94-
it('should throw useful type error for lenght', async () => {
94+
it('should throw useful type error for length', async () => {
9595
let schema = tuple([string().label('name'), number().label('age')]);
9696

9797
// expect(() => schema.cast(['James'])).toThrowError(

0 commit comments

Comments
 (0)