diff --git a/source/schema.d.ts b/source/schema.d.ts index 364192f95..2730f8e7e 100644 --- a/source/schema.d.ts +++ b/source/schema.d.ts @@ -47,25 +47,25 @@ export type Schema = ObjectType extends string ? ValueType : ObjectType extends ReadonlySet ? ValueType - : ObjectType extends readonly unknown[] - ? ValueType - : ObjectType extends unknown[] + : ObjectType extends Array + ? Array> + : 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 - : ValueType; + : ObjectType extends object + ? SchemaObject + : ValueType; /** Same as `Schema`, but accepts only `object`s as inputs. Internal helper for `Schema`. */ type SchemaObject = { - [KeyType in keyof ObjectType]: Schema | K; + [KeyType in keyof ObjectType]: ObjectType[KeyType] extends readonly unknown[] | unknown[] + ? Schema + : Schema | K; }; diff --git a/test-d/schema.ts b/test-d/schema.ts index 3200ea78c..8bcb44ba7 100644 --- a/test-d/schema.ts +++ b/test-d/schema.ts @@ -14,6 +14,7 @@ const foo = { set: new Set(), array: ['foo'], tuple: ['foo'] as ['foo'], + objectArray: [{key: 'value'}], readonlyMap: new Map() as ReadonlyMap, readonlySet: new Set() as ReadonlySet, readonlyArray: ['foo'] as readonly string[], @@ -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', }, }; @@ -60,12 +62,13 @@ expectType(barSchema.boolean); expectType(barSchema.symbol); expectType(barSchema.map); expectType(barSchema.set); -expectType(barSchema.array); -expectType(barSchema.tuple); +expectType(barSchema.array); +expectType(barSchema.tuple); +expectType>(barSchema.objectArray); expectType(barSchema.readonlyMap); expectType(barSchema.readonlySet); -expectType(barSchema.readonlyArray); -expectType(barSchema.readonlyTuple); +expectType(barSchema.readonlyArray); +expectType(barSchema.readonlyTuple); expectType(barSchema.regExp); type ComplexOption = { @@ -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'), }, }; @@ -114,10 +118,11 @@ expectType(complexBarSchema.boolean); expectType(complexBarSchema.symbol); expectType(complexBarSchema.map); expectType(complexBarSchema.set); -expectType(complexBarSchema.array); -expectType(complexBarSchema.tuple); +expectType(complexBarSchema.array); +expectType(complexBarSchema.tuple); +expectType>(complexBarSchema.objectArray); expectType(complexBarSchema.readonlyMap); expectType(complexBarSchema.readonlySet); -expectType(complexBarSchema.readonlyArray); -expectType(complexBarSchema.readonlyTuple); +expectType(complexBarSchema.readonlyArray); +expectType(complexBarSchema.readonlyTuple); expectType(complexBarSchema.regExp);