Skip to content

Commit

Permalink
Fix ObjectInput and ObjectOutput type #242
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian-hiller committed Dec 8, 2023
1 parent 43fc20d commit 2392109
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 31 deletions.
1 change: 1 addition & 0 deletions library/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to the library will be documented in this file.

- Add `bic` validation function (pull request #284)
- Add `mac`, `mac48` and `mac64` validation function (pull request #270)
- Fix optional keys of `ObjectInput` and `ObjectOutput` type (issue #242)

## v0.22.0 (December 03, 2023)

Expand Down
69 changes: 38 additions & 31 deletions library/src/schemas/object/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
ResolveObject,
} from '../../types/index.ts';
import type { NeverSchema, NeverSchemaAsync } from '../never/index.ts';
import type { OptionalSchema, OptionalSchemaAsync } from '../optional/index.ts';
import type { ObjectEntries } from './object.ts';
import type { ObjectEntriesAsync } from './objectAsync.ts';

Expand All @@ -22,25 +23,47 @@ export type ObjectPathItem = {
/**
* Required object keys type.
*/
type RequiredKeys<TObject extends object> = {
[TKey in keyof TObject]: undefined extends TObject[TKey] ? never : TKey;
}[keyof TObject];
type RequiredKeys<TEntries extends ObjectEntries | ObjectEntriesAsync> = {
[TKey in keyof TEntries]: TEntries[TKey] extends
| OptionalSchema<any>
| OptionalSchemaAsync<any>
? never
: TKey;
}[keyof TEntries];

/**
* Optional object keys type.
*/
type OptionalKeys<TObject extends object> = {
[TKey in keyof TObject]: undefined extends TObject[TKey] ? TKey : never;
}[keyof TObject];
type OptionalKeys<TEntries extends ObjectEntries | ObjectEntriesAsync> = {
[TKey in keyof TEntries]: TEntries[TKey] extends
| OptionalSchema<any>
| OptionalSchemaAsync<any>
? TKey
: never;
}[keyof TEntries];

/**
* Entries input inference type.
*/
type EntriesInput<TEntries extends ObjectEntries | ObjectEntriesAsync> = {
[TKey in keyof TEntries]: Input<TEntries[TKey]>;
};

/**
* Entries output inference type.
*/
type EntriesOutput<TEntries extends ObjectEntries | ObjectEntriesAsync> = {
[TKey in keyof TEntries]: Output<TEntries[TKey]>;
};

/**
* Object with question marks type.
*/
type WithQuestionMarks<TObject extends object> = Pick<
TObject,
RequiredKeys<TObject>
> &
Partial<Pick<TObject, OptionalKeys<TObject>>>;
type WithQuestionMarks<
TEntries extends ObjectEntries | ObjectEntriesAsync,
TObject extends EntriesInput<TEntries> | EntriesOutput<TEntries>
> = Pick<TObject, RequiredKeys<TEntries>> &
Partial<Pick<TObject, OptionalKeys<TEntries>>>;

/**
* Object input inference type.
Expand All @@ -49,17 +72,9 @@ export type ObjectInput<
TEntries extends ObjectEntries | ObjectEntriesAsync,
TRest extends BaseSchema | BaseSchemaAsync | undefined
> = TRest extends undefined | NeverSchema | NeverSchemaAsync
? ResolveObject<
WithQuestionMarks<{
[TKey in keyof TEntries]: Input<TEntries[TKey]>;
}>
>
? ResolveObject<WithQuestionMarks<TEntries, EntriesInput<TEntries>>>
: TRest extends BaseSchema | BaseSchemaAsync
? ResolveObject<
WithQuestionMarks<{
[TKey in keyof TEntries]: Input<TEntries[TKey]>;
}>
> &
? ResolveObject<WithQuestionMarks<TEntries, EntriesInput<TEntries>>> &
Record<string, Input<TRest>>
: never;

Expand All @@ -70,16 +85,8 @@ export type ObjectOutput<
TEntries extends ObjectEntries | ObjectEntriesAsync,
TRest extends BaseSchema | BaseSchemaAsync | undefined
> = TRest extends undefined | NeverSchema | NeverSchemaAsync
? ResolveObject<
WithQuestionMarks<{
[TKey in keyof TEntries]: Output<TEntries[TKey]>;
}>
>
? ResolveObject<WithQuestionMarks<TEntries, EntriesOutput<TEntries>>>
: TRest extends BaseSchema | BaseSchemaAsync
? ResolveObject<
WithQuestionMarks<{
[TKey in keyof TEntries]: Output<TEntries[TKey]>;
}>
> &
? ResolveObject<WithQuestionMarks<TEntries, EntriesOutput<TEntries>>> &
Record<string, Output<TRest>>
: never;

0 comments on commit 2392109

Please sign in to comment.