From bba8edbb675c9cd339347529ae1908dbfc25b02a Mon Sep 17 00:00:00 2001 From: ASafaierad Date: Wed, 27 Dec 2023 12:17:29 +0100 Subject: [PATCH] fix: make isRequired private --- src/Config.spec.ts | 4 ++-- src/Config.ts | 4 ++-- src/Schema/ObjectSchema.ts | 12 ++++++++---- src/Schema/Schema.spec.ts | 2 +- src/Schema/Schema.ts | 13 +++++++++---- src/types.ts | 13 ++++++++----- 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/Config.spec.ts b/src/Config.spec.ts index bcb5576..2220ec6 100644 --- a/src/Config.spec.ts +++ b/src/Config.spec.ts @@ -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() }), }), }) diff --git a/src/Config.ts b/src/Config.ts index 956b6fb..20d1458 100644 --- a/src/Config.ts +++ b/src/Config.ts @@ -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> { +export class Config>> { private value!: InferSchema; constructor(private schema: TSchema) {} @@ -46,7 +46,7 @@ export class Config> { return new NumberSchema(options) as any; } - static object>( + static object>>( schema: T, ): RequiredSchema> { return new ObjectSchema(schema) as any; diff --git a/src/Schema/ObjectSchema.ts b/src/Schema/ObjectSchema.ts index b6b2021..d66e64b 100644 --- a/src/Schema/ObjectSchema.ts +++ b/src/Schema/ObjectSchema.ts @@ -2,7 +2,7 @@ import type { Guard } from '../Guard'; import { Schema } from './Schema'; class ObjectGuard implements Guard> { - constructor(private schema: Record) {} + constructor(private schema: Record>) {} validate(input: Record | undefined, key: string) { if (!input) return; @@ -16,15 +16,19 @@ class ObjectGuard implements Guard> { } } -export class ObjectSchema extends Schema { +export class ObjectSchema extends Schema< + TInput, + TInput, + boolean +> { #type = 'object'; // eslint-disable-line no-unused-private-class-members - constructor(schema: Record) { + constructor(schema: Record>) { super({ typeConstructor: x => x, type: 'object', }); - this.require(); + this.required(); this.guards.push(new ObjectGuard(schema)); } } diff --git a/src/Schema/Schema.spec.ts b/src/Schema/Schema.spec.ts index 74c8e2e..27d0121 100644 --- a/src/Schema/Schema.spec.ts +++ b/src/Schema/Schema.spec.ts @@ -6,7 +6,7 @@ describe('Schema', () => { const schema = new Schema({ type: 'string', typeConstructor: String, - }).require(); + }).required(); schema.key = 'port'; expect(() => schema.validate()).toThrow( diff --git a/src/Schema/Schema.ts b/src/Schema/Schema.ts index d790292..9fceaf8 100644 --- a/src/Schema/Schema.ts +++ b/src/Schema/Schema.ts @@ -30,12 +30,17 @@ interface SchemaOptions { coerce?: boolean; } -export class Schema { +export class Schema< + TInput = any, + TValue = any, + TRequired extends boolean = false, +> { protected input: TInput | undefined; protected guards: Guard[]; 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) { this.options.coerce ??= true; @@ -56,9 +61,9 @@ export class Schema { return this; } - public require() { + public required() { this.guards.unshift(new RequiredGuard()); - return this as this & { isRequired: true }; + return this as Schema; } public validate() { diff --git a/src/types.ts b/src/types.ts index 68fdf40..e31b69c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import type { Schema, StringSchema } from './Schema'; +import type { Schema } from './Schema'; import type { ObjectSchema } from './Schema/ObjectSchema'; export type Prettify = { @@ -8,15 +8,17 @@ export type Prettify = { export type InferObjectSchema = T extends ObjectSchema< infer G > - ? G extends Record + ? G extends Record> ? Prettify> : never : never; -export type InferSchema> = { +export type InferSchema< + T extends Record>, +> = { [K in keyof T]: T[K] extends ObjectSchema ? InferObjectSchema - : T[K]['isRequired'] extends true + : T[K] extends RequiredSchema ? NonNullable : T[K]['value']; }; @@ -29,4 +31,5 @@ export type Equals = (() => T extends X ? 1 : 2) extends < ? true : false; -export type RequiredSchema = T & { isRequired: true }; +export type RequiredSchema> = + T extends Schema ? Schema : T;