Skip to content

Commit

Permalink
Schema: Fix handling of arrays (#887)
Browse files Browse the repository at this point in the history
  • Loading branch information
grigorischristainas authored Jun 15, 2024
1 parent 7d4e875 commit c570ec2
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 28 deletions.
24 changes: 12 additions & 12 deletions source/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,25 @@ export type Schema<ObjectType, ValueType> = ObjectType extends string
? ValueType
: ObjectType extends ReadonlySet<unknown>
? ValueType
: ObjectType extends readonly unknown[]
? ValueType
: ObjectType extends unknown[]
: ObjectType extends Array<infer U>
? Array<Schema<U, ValueType>>
: ObjectType extends (...arguments_: unknown[]) => unknown
? ValueType
: ObjectType extends (...arguments_: unknown[]) => unknown
: ObjectType extends Date
? ValueType
: ObjectType extends Date
: ObjectType extends Function
? ValueType
: ObjectType extends Function
: ObjectType extends RegExp
? ValueType
: ObjectType extends RegExp
? ValueType
: ObjectType extends object
? SchemaObject<ObjectType, ValueType>
: ValueType;
: ObjectType extends object
? SchemaObject<ObjectType, ValueType>
: ValueType;

/**
Same as `Schema`, but accepts only `object`s as inputs. Internal helper for `Schema`.
*/
type SchemaObject<ObjectType extends object, K> = {
[KeyType in keyof ObjectType]: Schema<ObjectType[KeyType], K> | K;
[KeyType in keyof ObjectType]: ObjectType[KeyType] extends readonly unknown[] | unknown[]
? Schema<ObjectType[KeyType], K>
: Schema<ObjectType[KeyType], K> | K;
};
37 changes: 21 additions & 16 deletions test-d/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const foo = {
set: new Set<string>(),
array: ['foo'],
tuple: ['foo'] as ['foo'],
objectArray: [{key: 'value'}],
readonlyMap: new Map<string, string>() as ReadonlyMap<string, string>,
readonlySet: new Set<string>() as ReadonlySet<string>,
readonlyArray: ['foo'] as readonly string[],
Expand All @@ -36,12 +37,13 @@ const fooSchema: FooSchema = {
symbol: 'A',
map: 'A',
set: 'A',
array: 'A',
tuple: 'A',
array: ['A'],
tuple: ['A'],
objectArray: [{key: 'A'}],
readonlyMap: 'A',
readonlySet: 'A',
readonlyArray: 'A',
readonlyTuple: 'A',
readonlyArray: ['A'] as const,
readonlyTuple: ['A'] as const,
regExp: 'A',
},
};
Expand All @@ -60,12 +62,13 @@ expectType<FooOption>(barSchema.boolean);
expectType<FooOption>(barSchema.symbol);
expectType<FooOption>(barSchema.map);
expectType<FooOption>(barSchema.set);
expectType<FooOption>(barSchema.array);
expectType<FooOption>(barSchema.tuple);
expectType<FooOption[]>(barSchema.array);
expectType<FooOption[]>(barSchema.tuple);
expectType<Array<{key: FooOption}>>(barSchema.objectArray);
expectType<FooOption>(barSchema.readonlyMap);
expectType<FooOption>(barSchema.readonlySet);
expectType<FooOption>(barSchema.readonlyArray);
expectType<FooOption>(barSchema.readonlyTuple);
expectType<readonly FooOption[]>(barSchema.readonlyArray);
expectType<readonly [FooOption]>(barSchema.readonlyTuple);
expectType<FooOption>(barSchema.regExp);

type ComplexOption = {
Expand All @@ -92,12 +95,13 @@ const complexFoo: ComplexSchema = {
symbol: createComplexOption('readonly'),
map: createComplexOption('readonly'),
set: createComplexOption('readonly'),
array: createComplexOption('readonly'),
tuple: createComplexOption('readonly'),
array: [createComplexOption('readonly')],
tuple: [createComplexOption('readonly')],
objectArray: [{key: createComplexOption('readonly')}],
readonlyMap: createComplexOption('readonly'),
readonlySet: createComplexOption('readonly'),
readonlyArray: createComplexOption('readonly'),
readonlyTuple: createComplexOption('readonly'),
readonlyArray: [createComplexOption('readonly')] as const,
readonlyTuple: [createComplexOption('readonly')] as const,
regExp: createComplexOption('readonly'),
},
};
Expand All @@ -114,10 +118,11 @@ expectType<ComplexOption>(complexBarSchema.boolean);
expectType<ComplexOption>(complexBarSchema.symbol);
expectType<ComplexOption>(complexBarSchema.map);
expectType<ComplexOption>(complexBarSchema.set);
expectType<ComplexOption>(complexBarSchema.array);
expectType<ComplexOption>(complexBarSchema.tuple);
expectType<ComplexOption[]>(complexBarSchema.array);
expectType<ComplexOption[]>(complexBarSchema.tuple);
expectType<Array<{key: ComplexOption}>>(complexBarSchema.objectArray);
expectType<ComplexOption>(complexBarSchema.readonlyMap);
expectType<ComplexOption>(complexBarSchema.readonlySet);
expectType<ComplexOption>(complexBarSchema.readonlyArray);
expectType<ComplexOption>(complexBarSchema.readonlyTuple);
expectType<readonly ComplexOption[]>(complexBarSchema.readonlyArray);
expectType<readonly [ComplexOption]>(complexBarSchema.readonlyTuple);
expectType<ComplexOption>(complexBarSchema.regExp);

0 comments on commit c570ec2

Please sign in to comment.