Skip to content

Commit

Permalink
Fix output type of nullable, nullish and optional #593
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian-hiller committed May 23, 2024
1 parent 49bb406 commit dde5687
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 56 deletions.
2 changes: 1 addition & 1 deletion library/src/methods/fallback/fallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export type SchemaWithFallback<
*/
export function fallback<
const TSchema extends BaseSchema<unknown, unknown, BaseIssue<unknown>>,
TFallback extends Fallback<TSchema>,
const TFallback extends Fallback<TSchema>,
>(
schema: TSchema,
fallback: TFallback
Expand Down
2 changes: 1 addition & 1 deletion library/src/methods/fallback/fallbackAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export function fallbackAsync<
const TSchema extends
| BaseSchema<unknown, unknown, BaseIssue<unknown>>
| BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>,
TFallback extends FallbackAsync<TSchema>,
const TFallback extends FallbackAsync<TSchema>,
>(
schema: TSchema,
fallback: TFallback
Expand Down
1 change: 1 addition & 0 deletions library/src/schemas/nullable/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './nullable.ts';
export * from './nullableAsync.ts';
export * from './types.ts';
12 changes: 3 additions & 9 deletions library/src/schemas/nullable/nullable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import type {
BaseSchema,
Dataset,
Default,
DefaultValue,
InferInput,
InferIssue,
InferOutput,
NonNullable,
} from '../../types/index.ts';
import type { InferNullableOutput } from './types.ts';

/**
* Nullable schema type.
Expand All @@ -19,11 +17,7 @@ export interface NullableSchema<
TDefault extends Default<TWrapped, null>,
> extends BaseSchema<
InferInput<TWrapped> | null,
[TDefault] extends [never]
? InferOutput<TWrapped> | null
: // FIXME: For schemas that transform the input to `null`, this
// implementation may result in an incorrect output type
NonNullable<InferOutput<TWrapped>> | DefaultValue<TDefault>,
InferNullableOutput<TWrapped, TDefault>,
InferIssue<TWrapped>
> {
/**
Expand Down Expand Up @@ -69,7 +63,7 @@ export function nullable<
*/
export function nullable<
const TWrapped extends BaseSchema<unknown, unknown, BaseIssue<unknown>>,
TDefault extends Default<TWrapped, null>,
const TDefault extends Default<TWrapped, null>,
>(wrapped: TWrapped, default_: TDefault): NullableSchema<TWrapped, TDefault>;

export function nullable(
Expand Down
12 changes: 3 additions & 9 deletions library/src/schemas/nullable/nullableAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import type {
BaseSchemaAsync,
Dataset,
DefaultAsync,
DefaultValue,
InferInput,
InferIssue,
InferOutput,
NonNullable,
} from '../../types/index.ts';
import type { InferNullableOutput } from './types.ts';

/**
* Nullable schema async type.
Expand All @@ -22,11 +20,7 @@ export interface NullableSchemaAsync<
TDefault extends DefaultAsync<TWrapped, null>,
> extends BaseSchemaAsync<
InferInput<TWrapped> | null,
[TDefault] extends [never]
? InferOutput<TWrapped> | null
: // FIXME: For schemas that transform the input to `null`, this
// implementation may result in an incorrect output type
NonNullable<InferOutput<TWrapped>> | DefaultValue<TDefault>,
InferNullableOutput<TWrapped, TDefault>,
InferIssue<TWrapped>
> {
/**
Expand Down Expand Up @@ -76,7 +70,7 @@ export function nullableAsync<
const TWrapped extends
| BaseSchema<unknown, unknown, BaseIssue<unknown>>
| BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>,
TDefault extends DefaultAsync<TWrapped, null>,
const TDefault extends DefaultAsync<TWrapped, null>,
>(
wrapped: TWrapped,
default_: TDefault
Expand Down
23 changes: 23 additions & 0 deletions library/src/schemas/nullable/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type {
BaseIssue,
BaseSchema,
BaseSchemaAsync,
DefaultAsync,
DefaultValue,
InferOutput,
NonNullable,
} from '../../types/index.ts';

/**
* Infer nullable output type.
*/
export type InferNullableOutput<
TWrapped extends
| BaseSchema<unknown, unknown, BaseIssue<unknown>>
| BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>,
TDefault extends DefaultAsync<TWrapped, undefined>,
> = [TDefault] extends [never]
? InferOutput<TWrapped> | null
: // FIXME: For schemas that transform the input to `undefined`, this
// implementation may result in an incorrect output type
NonNullable<InferOutput<TWrapped>> | Extract<DefaultValue<TDefault>, null>;
1 change: 1 addition & 0 deletions library/src/schemas/nullish/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './nullish.ts';
export * from './nullishAsync.ts';
export * from './types.ts';
12 changes: 3 additions & 9 deletions library/src/schemas/nullish/nullish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import type {
BaseSchema,
Dataset,
Default,
DefaultValue,
InferInput,
InferIssue,
InferOutput,
NonNullish,
} from '../../types/index.ts';
import type { InferNullishOutput } from './types.ts';

/**
* Nullish schema type.
Expand All @@ -19,11 +17,7 @@ export interface NullishSchema<
TDefault extends Default<TWrapped, null | undefined>,
> extends BaseSchema<
InferInput<TWrapped> | null | undefined,
[TDefault] extends [never]
? InferOutput<TWrapped> | null | undefined
: // FIXME: For schemas that transform the input to `null` or `undefined`,
// this implementation may result in an incorrect output type
NonNullish<InferOutput<TWrapped>> | DefaultValue<TDefault>,
InferNullishOutput<TWrapped, TDefault>,
InferIssue<TWrapped>
> {
/**
Expand Down Expand Up @@ -69,7 +63,7 @@ export function nullish<
*/
export function nullish<
const TWrapped extends BaseSchema<unknown, unknown, BaseIssue<unknown>>,
TDefault extends Default<TWrapped, null | undefined>,
const TDefault extends Default<TWrapped, null | undefined>,
>(wrapped: TWrapped, default_: TDefault): NullishSchema<TWrapped, TDefault>;

export function nullish(
Expand Down
12 changes: 3 additions & 9 deletions library/src/schemas/nullish/nullishAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import type {
BaseSchemaAsync,
Dataset,
DefaultAsync,
DefaultValue,
InferInput,
InferIssue,
InferOutput,
NonNullish,
} from '../../types/index.ts';
import type { InferNullishOutput } from './types.ts';

/**
* Nullish schema async type.
Expand All @@ -22,11 +20,7 @@ export interface NullishSchemaAsync<
TDefault extends DefaultAsync<TWrapped, null | undefined>,
> extends BaseSchemaAsync<
InferInput<TWrapped> | null | undefined,
[TDefault] extends [never]
? InferOutput<TWrapped> | null | undefined
: // FIXME: For schemas that transform the input to `null` or `undefined`,
// this implementation may result in an incorrect output type
NonNullish<InferOutput<TWrapped>> | DefaultValue<TDefault>,
InferNullishOutput<TWrapped, TDefault>,
InferIssue<TWrapped>
> {
/**
Expand Down Expand Up @@ -76,7 +70,7 @@ export function nullishAsync<
const TWrapped extends
| BaseSchema<unknown, unknown, BaseIssue<unknown>>
| BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>,
TDefault extends DefaultAsync<TWrapped, null | undefined>,
const TDefault extends DefaultAsync<TWrapped, null | undefined>,
>(
wrapped: TWrapped,
default_: TDefault
Expand Down
24 changes: 24 additions & 0 deletions library/src/schemas/nullish/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type {
BaseIssue,
BaseSchema,
BaseSchemaAsync,
DefaultAsync,
DefaultValue,
InferOutput,
NonNullish,
} from '../../types/index.ts';

/**
* Infer nullish output type.
*/
export type InferNullishOutput<
TWrapped extends
| BaseSchema<unknown, unknown, BaseIssue<unknown>>
| BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>,
TDefault extends DefaultAsync<TWrapped, undefined>,
> = [TDefault] extends [never]
? InferOutput<TWrapped> | null | undefined
: // FIXME: For schemas that transform the input to `undefined`, this
// implementation may result in an incorrect output type
| NonNullish<InferOutput<TWrapped>>
| Extract<DefaultValue<TDefault>, null | undefined>;
1 change: 1 addition & 0 deletions library/src/schemas/optional/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './optional.ts';
export * from './optionalAsync.ts';
export * from './types.ts';
12 changes: 3 additions & 9 deletions library/src/schemas/optional/optional.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import type {
BaseSchema,
Dataset,
Default,
DefaultValue,
InferInput,
InferIssue,
InferOutput,
NonOptional,
} from '../../types/index.ts';
import type { InferOptionalOutput } from './types.ts';

/**
* Optional schema type.
Expand All @@ -19,11 +17,7 @@ export interface OptionalSchema<
TDefault extends Default<TWrapped, undefined>,
> extends BaseSchema<
InferInput<TWrapped> | undefined,
[TDefault] extends [never]
? InferOutput<TWrapped> | undefined
: // FIXME: For schemas that transform the input to `undefined`, this
// implementation may result in an incorrect output type
NonOptional<InferOutput<TWrapped>> | DefaultValue<TDefault>,
InferOptionalOutput<TWrapped, TDefault>,
InferIssue<TWrapped>
> {
/**
Expand Down Expand Up @@ -69,7 +63,7 @@ export function optional<
*/
export function optional<
const TWrapped extends BaseSchema<unknown, unknown, BaseIssue<unknown>>,
TDefault extends Default<TWrapped, undefined>,
const TDefault extends Default<TWrapped, undefined>,
>(wrapped: TWrapped, default_: TDefault): OptionalSchema<TWrapped, TDefault>;

export function optional(
Expand Down
12 changes: 3 additions & 9 deletions library/src/schemas/optional/optionalAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import type {
BaseSchemaAsync,
Dataset,
DefaultAsync,
DefaultValue,
InferInput,
InferIssue,
InferOutput,
NonOptional,
} from '../../types/index.ts';
import type { InferOptionalOutput } from './types.ts';

/**
* Optional schema async type.
Expand All @@ -22,11 +20,7 @@ export interface OptionalSchemaAsync<
TDefault extends DefaultAsync<TWrapped, undefined>,
> extends BaseSchemaAsync<
InferInput<TWrapped> | undefined,
[TDefault] extends [never]
? InferOutput<TWrapped> | undefined
: // FIXME: For schemas that transform the input to `undefined`, this
// implementation may result in an incorrect output type
NonOptional<InferOutput<TWrapped>> | DefaultValue<TDefault>,
InferOptionalOutput<TWrapped, TDefault>,
InferIssue<TWrapped>
> {
/**
Expand Down Expand Up @@ -76,7 +70,7 @@ export function optionalAsync<
const TWrapped extends
| BaseSchema<unknown, unknown, BaseIssue<unknown>>
| BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>,
TDefault extends DefaultAsync<TWrapped, undefined>,
const TDefault extends DefaultAsync<TWrapped, undefined>,
>(
wrapped: TWrapped,
default_: TDefault
Expand Down
24 changes: 24 additions & 0 deletions library/src/schemas/optional/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type {
BaseIssue,
BaseSchema,
BaseSchemaAsync,
DefaultAsync,
DefaultValue,
InferOutput,
NonOptional,
} from '../../types/index.ts';

/**
* Infer optional output type.
*/
export type InferOptionalOutput<
TWrapped extends
| BaseSchema<unknown, unknown, BaseIssue<unknown>>
| BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>,
TDefault extends DefaultAsync<TWrapped, undefined>,
> = [TDefault] extends [never]
? InferOutput<TWrapped> | undefined
: // FIXME: For schemas that transform the input to `undefined`, this
// implementation may result in an incorrect output type
| NonOptional<InferOutput<TWrapped>>
| Extract<DefaultValue<TDefault>, undefined>;

0 comments on commit dde5687

Please sign in to comment.