Skip to content

Commit

Permalink
fix: make isRequired private
Browse files Browse the repository at this point in the history
  • Loading branch information
ASafaeirad committed Apr 13, 2024
1 parent b4d9675 commit a850413
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 18 deletions.
4 changes: 2 additions & 2 deletions src/Config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ describe('Config', () => {
it('should parse nested object', () => {
const config = new Config({
s: Config.string(),
n: Config.number().require(),
n: Config.number().required(),
foo: Config.object({
foo1: Config.string().require(),
foo1: Config.string().required(),
foo2: Config.object({ foo3: Config.boolean() }),
}),
})
Expand Down
4 changes: 2 additions & 2 deletions src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ObjectSchema } from './Schema/ObjectSchema';
import type { SchemaWithDefaultOptions } from './Schema/SchemaOptions';
import type { InferSchema, Prettify, RequiredSchema } from './types';

export class Config<TSchema extends Record<string, Schema>> {
export class Config<TSchema extends Record<string, Schema<any, any, boolean>>> {
private value!: InferSchema<TSchema>;

constructor(private schema: TSchema) {}
Expand Down Expand Up @@ -46,7 +46,7 @@ export class Config<TSchema extends Record<string, Schema>> {
return new NumberSchema(options) as any;
}

static object<T extends Record<string, Schema>>(
static object<T extends Record<string, Schema<any, any, boolean>>>(
schema: T,
): RequiredSchema<ObjectSchema<T>> {
return new ObjectSchema(schema) as any;
Expand Down
12 changes: 8 additions & 4 deletions src/Schema/ObjectSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Guard } from '../Guard';
import { Schema } from './Schema';

class ObjectGuard implements Guard<Record<string, Schema>> {
constructor(private schema: Record<string, Schema>) {}
constructor(private schema: Record<string, Schema<any, any, boolean>>) {}

validate(input: Record<string, unknown> | undefined, key: string) {
if (!input) return;
Expand All @@ -16,15 +16,19 @@ class ObjectGuard implements Guard<Record<string, Schema>> {
}
}

export class ObjectSchema<TInput = any> extends Schema<TInput, TInput> {
export class ObjectSchema<TInput = any> extends Schema<
TInput,
TInput,
boolean
> {
#type = 'object'; // eslint-disable-line no-unused-private-class-members

constructor(schema: Record<string, Schema>) {
constructor(schema: Record<string, Schema<any, any, boolean>>) {
super({
typeConstructor: x => x,
type: 'object',
});
this.require();
this.required();
this.guards.push(new ObjectGuard(schema));
}
}
2 changes: 1 addition & 1 deletion src/Schema/Schema.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('Schema', () => {
const schema = new Schema({
type: 'string',
typeConstructor: String,
}).require();
}).required();
schema.key = 'port';

expect(() => schema.validate()).toThrow(
Expand Down
13 changes: 9 additions & 4 deletions src/Schema/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@ interface SchemaOptions<TInput, TValue> {
coerce?: boolean;
}

export class Schema<TInput = any, TValue = any> {
export class Schema<
TInput = any,
TValue = any,
TRequired extends boolean = false,
> {
protected input: TInput | undefined;
protected guards: Guard<any>[];
public value: TValue | undefined;
public key!: string;
public isRequired!: boolean;
// @ts-expect-error Metadata for type-safety
#isRequired: TRequired; // eslint-disable-line no-unused-private-class-members

constructor(public options: SchemaOptions<TInput, TValue>) {
this.options.coerce ??= true;
Expand All @@ -56,9 +61,9 @@ export class Schema<TInput = any, TValue = any> {
return this;
}

public require() {
public required() {
this.guards.unshift(new RequiredGuard());
return this as this & { isRequired: true };
return this as Schema<TInput, TValue, true>;
}

public validate() {
Expand Down
13 changes: 8 additions & 5 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Schema, StringSchema } from './Schema';
import type { Schema } from './Schema';
import type { ObjectSchema } from './Schema/ObjectSchema';

export type Prettify<T> = {
Expand All @@ -8,15 +8,17 @@ export type Prettify<T> = {
export type InferObjectSchema<T extends ObjectSchema> = T extends ObjectSchema<
infer G
>
? G extends Record<string, Schema>
? G extends Record<string, Schema<any, any, boolean>>
? Prettify<InferSchema<G>>
: never
: never;

export type InferSchema<T extends Record<string, Schema>> = {
export type InferSchema<
T extends Record<string, Schema<unknown, unknown, boolean>>,
> = {
[K in keyof T]: T[K] extends ObjectSchema
? InferObjectSchema<T[K]>
: T[K]['isRequired'] extends true
: T[K] extends RequiredSchema<T[K]>
? NonNullable<T[K]['value']>
: T[K]['value'];
};
Expand All @@ -29,4 +31,5 @@ export type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
? true
: false;

export type RequiredSchema<T extends Schema> = T & { isRequired: true };
export type RequiredSchema<T extends Schema<any, any, boolean>> =
T extends Schema<infer I, infer O> ? Schema<I, O, true> : T;

0 comments on commit a850413

Please sign in to comment.