Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use interface instead of type for all Base types #259

Merged
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
fd86987
Use `interface` instead of `type` for all Base types
Saeris Nov 19, 2023
990140a
Refactor Fallback and Default methods, Add Schema Type Predicates
Saeris Nov 21, 2023
cc38e4f
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Nov 21, 2023
5b483f4
Fix file extensions lint errors
Saeris Nov 22, 2023
a6bbcd1
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Nov 22, 2023
a1584f1
Add jsdoc `@param` and `@returns` required by linting rules
Saeris Nov 22, 2023
c08f732
Resolve Flatten type errors
Saeris Nov 22, 2023
7f84338
Fix broken export for `intersectAsync`
Saeris Nov 22, 2023
cab5616
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Dec 5, 2023
a89b486
Fix eslint error
Saeris Dec 5, 2023
3b2d314
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Dec 5, 2023
1b516da
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Jan 6, 2024
5078f72
Resolve lint errors (no-extra-semi)
Saeris Jan 6, 2024
27dec16
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Jan 8, 2024
6949d2d
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Jan 18, 2024
c2dc365
Fix extra semi errors from merge
Saeris Jan 18, 2024
527a05c
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Jan 18, 2024
e5c79ca
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Jan 19, 2024
0a426bb
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Jan 21, 2024
e195488
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Jan 24, 2024
0676aff
Fix merge errors
Saeris Jan 24, 2024
0604c26
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Feb 5, 2024
bb424a0
Fix formatting
Saeris Feb 5, 2024
b6a2fb2
Merge branch 'main' into feat/use-interface-for-base-types
fabian-hiller Feb 17, 2024
0a5889a
Fix types and exports of fallback method
fabian-hiller Feb 17, 2024
fe36ae1
Add `isOfType` utility and refactor type guard implementations
Saeris Feb 27, 2024
9574d5d
Merge branch 'feat/use-interface-for-base-types' of https://github.co…
Saeris Feb 27, 2024
2a28529
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Mar 4, 2024
48ce458
Merge branch 'main' into feat/use-interface-for-base-types
Saeris Mar 4, 2024
02b17d5
run prettier and fix lint warnings
Saeris Mar 4, 2024
2cefacc
Add Default and DefaultAsync type and refactor codebase
fabian-hiller Mar 6, 2024
114b1f8
Add Fallback and FallbackAsync type and refactor codebase
fabian-hiller Mar 6, 2024
e08af7f
Refactor getDefaults and getFallbacks method
fabian-hiller Mar 6, 2024
03e95e3
Undo changes of NestedPath type in flatten
fabian-hiller Mar 6, 2024
7e79352
Rename hasType to isOfType and refactor codebase
fabian-hiller Mar 6, 2024
2f77fc2
Add Default and Fallback to API reference of website
fabian-hiller Mar 6, 2024
de1d857
Update changelog of library
fabian-hiller Mar 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions library/src/error/flatten/flatten.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ type NestedPath<TSchema extends BaseSchema | BaseSchemaAsync> =
TSchema extends
| ObjectSchema<infer TEntries, infer TRest>
| ObjectSchemaAsync<infer TEntries, infer TRest>
? TRest extends BaseSchema | BaseSchemaAsync
fabian-hiller marked this conversation as resolved.
Show resolved Hide resolved
? TRest extends NonNullable<TRest>
? ObjectPath<TEntries> | DotPath<string, TRest>
: ObjectPath<TEntries>
: // Record
Expand All @@ -102,7 +102,7 @@ type NestedPath<TSchema extends BaseSchema | BaseSchemaAsync> =
TSchema extends
| TupleSchema<infer TItems, infer TRest>
| TupleSchemaAsync<infer TItems, infer TRest>
? TRest extends BaseSchema | BaseSchemaAsync
? TRest extends NonNullable<TRest>
? TuplePath<TItems> | DotPath<number, TRest>
: TuplePath<TItems>
: // Union
Expand Down
12 changes: 4 additions & 8 deletions library/src/methods/fallback/fallback.ts
fabian-hiller marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,13 @@ import type { FallbackInfo } from './types.ts';
/**
* Schema with fallback type.
*/
export type SchemaWithFallback<
TSchema extends BaseSchema = BaseSchema,
TFallback extends
| Output<TSchema>
| ((info?: FallbackInfo) => Output<TSchema>) = Output<TSchema>
> = TSchema & {
export interface SchemaWithFallback<TInput = any, TOutput = TInput>
extends BaseSchema<TInput, TOutput> {
fabian-hiller marked this conversation as resolved.
Show resolved Hide resolved
/**
* The fallback value.
*/
fallback: TFallback;
};
fallback: TOutput | ((info?: FallbackInfo) => TOutput);
}

/**
* Returns a fallback output value when validating the passed schema failed.
Expand Down
14 changes: 4 additions & 10 deletions library/src/methods/fallback/fallbackAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,13 @@ import type { FallbackInfo } from './types.ts';
/**
* Schema with fallback async type.
*/
export type SchemaWithFallbackAsync<
TSchema extends BaseSchemaAsync = BaseSchemaAsync,
TFallback extends
| Output<TSchema>
| ((
info?: FallbackInfo
) => Output<TSchema> | Promise<Output<TSchema>>) = Output<TSchema>
> = TSchema & {
export interface SchemaWithFallbackAsync<TInput = any, TOutput = TInput>
extends BaseSchemaAsync<TInput, TOutput> {
fabian-hiller marked this conversation as resolved.
Show resolved Hide resolved
/**
* The fallback value.
*/
fallback: TFallback;
};
fallback: TOutput | ((info?: FallbackInfo) => TOutput | Promise<TOutput>);
}

/**
* Returns a fallback output value when validating the passed schema failed.
Expand Down
14 changes: 1 addition & 13 deletions library/src/methods/getDefault/getDefault.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
import type { BaseSchema, Output } from '../../types/index.ts';
import type { DefaultValue } from './types.ts';

/**
* Schema with maybe default type.
*/
export type SchemaWithMaybeDefault<TSchema extends BaseSchema = BaseSchema> =
TSchema & {
/**
* The optional default value.
*/
default?: Output<TSchema> | (() => Output<TSchema> | undefined);
};
import type { DefaultValue, SchemaWithMaybeDefault } from './types.ts';

/**
* Returns the default value of the schema.
Expand Down
25 changes: 5 additions & 20 deletions library/src/methods/getDefault/getDefaultAsync.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,8 @@
import type { BaseSchemaAsync, Output } from '../../types/index.ts';
import type { SchemaWithMaybeDefault } from './getDefault.ts';
import type { DefaultValue } from './types.ts';

/**
* Schema with maybe default async type.
*/
export type SchemaWithMaybeDefaultAsync<
TSchema extends BaseSchemaAsync = BaseSchemaAsync
> = TSchema & {
/**
* The optional default value.
*/
default?:
| Output<TSchema>
| (() =>
| Output<TSchema>
| Promise<Output<TSchema> | undefined>
| undefined);
};
import type {
DefaultValue,
SchemaWithMaybeDefault,
SchemaWithMaybeDefaultAsync,
} from './types.ts';

/**
* Returns the default value of the schema.
Expand Down
28 changes: 25 additions & 3 deletions library/src/methods/getDefault/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
import type { Output } from '../../types/index.ts';
import type { SchemaWithMaybeDefault } from './getDefault.ts';
import type { SchemaWithMaybeDefaultAsync } from './getDefaultAsync.ts';
import type { BaseSchema, BaseSchemaAsync, Output } from '../../types/index.ts';

/**
* Schema with maybe default type.
*/
export interface SchemaWithMaybeDefault<TInput = any, TOutput = TInput>
extends BaseSchema<TInput, TOutput> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this into getDefaults.ts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved these types because they created a circular dependency reference. IMO they are better kept in this file.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it create a circular dependency reference? I prefer to move it to getDefaults.ts to be consistent with the rest of the source code. Types that are related to a particular function are placed above the function in the same file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because for example:

export type DefaultValue<
  TSchema extends SchemaWithMaybeDefault | SchemaWithMaybeDefaultAsync,
>

in types.ts would import from getDefaults.ts, which itself imports DefaultValue from types,ts

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have a look at it. I don't think this is a problem but I could be wrong.

/**
fabian-hiller marked this conversation as resolved.
Show resolved Hide resolved
* The optional default value.
*/
default?: TOutput | (() => TOutput | undefined);
}

/**
* Schema with maybe default async type.
*/
export interface SchemaWithMaybeDefaultAsync<TInput = any, TOutput = TInput>
extends BaseSchemaAsync<TInput, TOutput> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this into getDefaultsAsync.ts

/**
* The optional default value.
*/
default?:
| TOutput
| (() => TOutput | Promise<TOutput | undefined> | undefined);
}

/**
* Default value inference type.
Expand Down
55 changes: 19 additions & 36 deletions library/src/methods/getDefaults/getDefaults.ts
fabian-hiller marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import type {
ObjectEntries,
ObjectSchema,
TupleItems,
TupleSchema,
} from '../../schemas/index.ts';
import type { BaseSchema } from '../../types/index.ts';
import { isObjectSchema, isTupleSchema } from '../../schemas/index.ts';
import {
getDefault,
type SchemaWithMaybeDefault,
Expand All @@ -22,36 +16,25 @@ import type { DefaultValues } from './types.ts';
*
* @returns The default values.
*/
export function getDefaults<
TSchema extends SchemaWithMaybeDefault<
BaseSchema | ObjectSchema<ObjectEntries, any> | TupleSchema<TupleItems, any>
>
>(schema: TSchema): DefaultValues<TSchema> {
// Create defaults variable
let defaults: any;

export function getDefaults<TSchema extends SchemaWithMaybeDefault>(
schema: TSchema
): DefaultValues<TSchema> | undefined {
// If schema contains a default function, set its default value
if (schema.default !== undefined) {
defaults = getDefault(schema);

// Otherwise, check if schema is of kind object or tuple
} else if ('type' in schema) {
// If it is an object schema, set object with default value of each entry
if (schema.type === 'object') {
defaults = {};
for (const key in schema.entries) {
defaults[key] = getDefaults(schema.entries[key]);
}

// If it is a tuple schema, set array with default value of each item
} else if (schema.type === 'tuple') {
defaults = [];
for (let key = 0; key < schema.items.length; key++) {
defaults.push(getDefaults(schema.items[key]));
}
}
return getDefault(schema);
}
// Otherwise, check if schema is of kind object or tuple
// If it is an object schema, set object with default value of each entry
if (isObjectSchema(schema)) {
return Object.fromEntries(
fabian-hiller marked this conversation as resolved.
Show resolved Hide resolved
Object.entries(schema.entries).map(([key, value]) => [
key,
getDefaults(value),
])
) as DefaultValues<TSchema>;
}
// If it is a tuple schema, set array with default value of each item
if (isTupleSchema(schema)) {
return schema.items.map(getDefaults) as DefaultValues<TSchema>;
}

// Return default values
return defaults;
}
69 changes: 22 additions & 47 deletions library/src/methods/getDefaults/getDefaultsAsync.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
import type {
ObjectEntries,
ObjectEntriesAsync,
ObjectSchema,
ObjectSchemaAsync,
TupleItems,
TupleItemsAsync,
TupleSchema,
TupleSchemaAsync,
} from '../../schemas/index.ts';
import type { BaseSchema, BaseSchemaAsync } from '../../types/index.ts';
import { isObjectSchema, isTupleSchema } from '../../schemas/index.ts';
import {
getDefaultAsync,
type SchemaWithMaybeDefault,
Expand All @@ -28,43 +18,28 @@ import type { DefaultValues } from './types.ts';
* @returns The default values.
*/
export async function getDefaultsAsync<
TSchema extends
| SchemaWithMaybeDefault<
| BaseSchema
| ObjectSchema<ObjectEntries, any>
| TupleSchema<TupleItems, any>
>
| SchemaWithMaybeDefaultAsync<
| BaseSchemaAsync
| ObjectSchemaAsync<ObjectEntriesAsync, any>
| TupleSchemaAsync<TupleItemsAsync, any>
>
>(schema: TSchema): Promise<DefaultValues<TSchema>> {
// Create defaults variable
let defaults: any;

TSchema extends SchemaWithMaybeDefault | SchemaWithMaybeDefaultAsync
>(schema: TSchema): Promise<DefaultValues<TSchema> | undefined> {
// If schema contains a default function, set its default value
if (schema.default !== undefined) {
defaults = await getDefaultAsync(schema);

// Otherwise, check if schema is of kind object or tuple
} else if ('type' in schema) {
// If it is an object schema, set object with default value of each entry
if (schema.type === 'object') {
defaults = {};
for (const key in schema.entries) {
defaults[key] = await getDefaultsAsync(schema.entries[key]);
}

// If it is a tuple schema, set array with default value of each item
} else if (schema.type === 'tuple') {
defaults = [];
for (let key = 0; key < schema.items.length; key++) {
defaults.push(await getDefaultsAsync(schema.items[key]));
}
}
return getDefaultAsync(schema);
}
// Otherwise, check if schema is of kind object or tuple
// If it is an object schema, set object with default value of each entry
if (isObjectSchema(schema)) {
return Object.fromEntries(
await Promise.all(
fabian-hiller marked this conversation as resolved.
Show resolved Hide resolved
Object.entries(schema.entries).map(async ([key, value]) => [
key,
await getDefaultsAsync(value),
])
)
);
}
// If it is a tuple schema, set array with default value of each item
if (isTupleSchema(schema)) {
return Promise.all(
schema.items.map(getDefaultsAsync)
) as DefaultValues<TSchema>;
}

// Return default values
return defaults;
}
14 changes: 1 addition & 13 deletions library/src/methods/getFallback/getFallback.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import type { BaseSchema, Output } from '../../types/index.ts';
import type { FallbackInfo } from '../fallback/types.ts';
import type { FallbackValue } from './types.ts';

/**
* Schema with maybe fallback type.
*/
export type SchemaWithMaybeFallback<TSchema extends BaseSchema = BaseSchema> =
TSchema & {
/**
* The optional fallback value.
*/
fallback?: Output<TSchema> | ((info?: FallbackInfo) => Output<TSchema>);
};
import type { FallbackValue, SchemaWithMaybeFallback } from './types.ts';

/**
* Returns the fallback value of the schema.
Expand Down
22 changes: 5 additions & 17 deletions library/src/methods/getFallback/getFallbackAsync.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import type { BaseSchemaAsync, Output } from '../../types/index.ts';
import type { FallbackInfo } from '../fallback/types.ts';
import type { SchemaWithMaybeFallback } from './getFallback.ts';
import type { FallbackValue } from './types.ts';

/**
* Schema with maybe fallback async type.
*/
export type SchemaWithMaybeFallbackAsync<
TSchema extends BaseSchemaAsync = BaseSchemaAsync
> = TSchema & {
/**
* The optional fallback value.
*/
fallback?:
| Output<TSchema>
| ((info?: FallbackInfo) => Output<TSchema> | Promise<Output<TSchema>>);
};
import type {
FallbackValue,
SchemaWithMaybeFallback,
SchemaWithMaybeFallbackAsync,
} from './types.ts';

/**
* Returns the fallback value of the schema.
Expand Down
27 changes: 24 additions & 3 deletions library/src/methods/getFallback/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
import type { Output } from '../../types/index.ts';
import type { SchemaWithMaybeFallback } from './getFallback.ts';
import type { SchemaWithMaybeFallbackAsync } from './getFallbackAsync.ts';
import type { BaseSchema, BaseSchemaAsync, Output } from '../../types/index.ts';
import type { FallbackInfo } from '../fallback/types.ts';

/**
* Schema with maybe fallback type.
*/
export interface SchemaWithMaybeFallback<TInput = any, TOutput = TInput>
extends BaseSchema<TInput, TOutput> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move that into getFallback.ts.

/**
* The optional fallback value.
*/
fallback?: TOutput | ((info?: FallbackInfo) => TOutput);
}

/**
* Schema with maybe fallback async type.
*/
export interface SchemaWithMaybeFallbackAsync<TInput = any, TOutput = TInput>
extends BaseSchemaAsync<TInput, TOutput> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move that into getFallbackAsync.ts.

/**
* The optional fallback value.
*/
fallback?: TOutput | ((info?: FallbackInfo) => TOutput | Promise<TOutput>);
}

/**
* Fallback value inference type.
Expand Down
Loading
Loading