feat(schema): export schema types, GetSchema<T>, ValidateReturn, and rule types#55
Merged
Conversation
…uentSchema results
…ports - Extract V3 namespace and BaseStruct to types/v3/index.ts - Add top-level re-exports of TUnion, TIntersection, TypeGuardTupleUnwrap - Redirect all V3 imports from types/index.ts to types/v3/index.ts - Redirect V3Helpers imports to v3/index.ts in UnionSchema, IntersectionSchema, TupleSchema - Remove local UnionSchema/TupleSchema type defs from or.ts/tuple.ts - Fix ValidateReturn import paths in FluentSchema and FluentOptionalSchema - Add canonical ValidateReturn.ts in validators/types/ - Re-export ValidateReturn from SchemaValidator.ts - Zero circular dependencies confirmed
- V1 extracted to v1/index.ts with own BaseStruct/BaseTypes - V2 extracted to v2/index.ts with own BaseStruct/BaseTypes - V1 kept only original types (Struct<T,U>, ArrayStruct<T,U>, etc.) - V3 convenience aliases removed from V1 (use V3.* directly) - types/index.ts imports V1/V2 via `import type * as`, re-exports them - Added top-level GenericStruct/ObjectStruct/Struct/StructType aliases to V3 for backward compat with consumers importing bare names
- V1/index.ts: remove PrimitiveStruct/AnyStruct/etc that were V3 aliases in original, not part of actual V1 namespace signature - types/index.ts: remove commented-out GetStruct implementation - FluentSchema.ts: remove commented-out import and AppendMessageMethod - GetSchema.spec.ts: strengthen type assertions with Assert wrappers for string literal, number literal, object, and optional object cases (prevents silent never regression)
Replace `export * from './v3/index.ts'` with an explicit allowlist of 4 flat V3 exports (BaseStruct, TUnion, TIntersection, TypeGuardTupleUnwrap). The wildcard leaked ~25 internal composition types into the public API (RequiredPartialStruct, OptionalPartialStruct, WithRulesStruct, MapToStructs, ExactExtends, IsExactExtension, ObjectTree, ClassInstanceRef, ArrayEntries, RecordMetadata, TupleMetadata, TupleToTypeGuardMap, TupleToStructMap, AsPrimitiveStruct, FromUnionStruct, FromIntersectionStruct, FromRecordStruct, FromClassInstanceStruct, FromTupleStruct). These remain accessible via the V3 namespace (V3.RequiredPartialStruct etc.) for internal consumers but are no longer re-exported flat. Also removed from public API surface: - Optionalize<T> — internal-only, no external consumers - GetSchemaStruct<T> — internal-only, no external consumers - RuleStruct<Rule> — internal dispatch type, not useful for consumers (test import redirected to rules/types/index.ts directly) - CUSTOM_RULE_BRAND — was already removed in prior commit; this cleans up the remaining export line
…a edge cases - Replace `export * from './types/index.ts'` in rules barrel with explicit type allowlist, preventing CUSTOM_RULE_BRAND (internal runtime symbol) and RuleStruct (internal dispatch type) from reaching the public API. Internal consumers still import these directly from ./types/index.ts. - Add `any` guard to GetSchema using `0 extends (1 & T)` pattern to prevent `any` from distributing through the string branch. GetSchema<any> now correctly resolves to FluentSchema<any>. - Add explicit `unknown` branch: GetSchema<unknown> resolves to FluentSchema<any> instead of never. - Broaden Record detection from `string extends keyof T` to `PropertyKey extends keyof T`, so Record<number, V> and Record<symbol, V> are correctly classified as records rather than specific objects. - Add type-level test assertions for GetSchema<any>, GetSchema<unknown>, and GetSchema<Record<number, string>>.
- NEVER disable GPG commit signing (no -c commit.gpgsign=false, --no-gpg-sign, or other bypasses). Stop and wait for user input. - NEVER continue past GPG pinentry failures. Stop all work immediately and wait for user direction.
70f41b8 to
dbd58ba
Compare
…nches PropertyKey extends keyof T never matched any Record because symbol doesn't extend string/number. Replace with per-key-type checks: string extends keyof T | number extends keyof T | symbol extends keyof T. Add void/never input branches, document unreachable never fallbacks, strengthen test assertions to strict RecordSchemaRules (not any), add Record<symbol,V>, void, never, function, Date test coverage.
…y array branch BooleanSchema previously returned FluentSchema<any> — a type-level mistake that masked a match test discriminated union issue. Fix BooleanSchema to FluentSchema<boolean> and widen match test Input type's discriminant from true to boolean. Add readonly array branch to GetSchema (T extends readonly (infer U)[]) before mutable array check, since readonly U[] doesn't extend U[]. Add readonly string[] test, fix JSDoc object examples to show Sanitize<T>, document RuleStruct internal import in test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/validators/schema/types/(BooleanSchema, NullSchema, UndefinedSchema, SymbolSchema, AnySchema, PrimitiveSchema, EnumSchema, ObjectSchema, TupleSchema, UnionSchema, IntersectionSchema)GetSchema<T>recursive type helper that maps TypeScript types to their correspondingFluentSchemaresult typesValidateReturn, and rule types (Custom,CustomFactory,Rule,CreateRuleArgs) from the types hubexport * from ./v3/index.tswildcard with explicit allowlist to prevent internal V3 composition types from leaking into the public APIexport * from ./types/index.tswildcard in rules barrel with explicit type allowlist to preventCUSTOM_RULE_BRAND(runtime symbol) andRuleStruct(internal dispatch type) from reaching the public APIOptionalize<T>,GetSchemaStruct<T>, andRuleStruct<Rule>from public exports (internal-only, no external consumers)GetSchemaedge cases:anyguard,unknown/void/neverbranches, Record detection for all key typesExports now available from
@srhenry/type-utilsGetSchema<T>ValidateReturn<T>BooleanSchema,NullSchema,UndefinedSchema,SymbolSchema,AnySchema,PrimitiveSchemaEnumSchema,ObjectSchema,TupleSchema,UnionSchema,IntersectionSchemaTupleSchemaEntry,UnionSchemaEntry,IntersectionSchemaEntryGetUnionEntryTypes,GetIntersectionEntryTypesCustom,CustomFactory,Rule,CreateRuleArgsV1,V2,V3BaseStruct,TUnion,TIntersection,TypeGuardTupleUnwrapGenericStruct,ObjectStruct,Struct,StructTypeKey change: V3 wildcard → explicit allowlist
The barrel file
src/validators/schema/types/index.tspreviously usedexport * from './v3/index.ts', which re-exported every type inside the V3 namespace flat — including ~25 internal composition types that consumers should never import directly:RequiredPartialStruct,OptionalPartialStruct,RequirefyStruct,OptionalizeStruct,WithRulesStruct,MapToStructs,ExactExtends,IsExactExtension,ObjectTree,ClassInstanceRef,ArrayEntries,RecordMetadata,TupleMetadata,TupleToTypeGuardMap,TupleToStructMap,AsPrimitiveStruct,FromUnionStruct,FromIntersectionStruct,FromRecordStruct,FromClassInstanceStruct,FromTupleStructThese types are still accessible to internal consumers via the
V3namespace (e.g.V3.RequiredPartialStruct), but they are no longer re-exported as bare names from the barrel. Only the 4 top-level flat exports fromv3/index.tsare explicitly allowed through:BaseStruct,TUnion,TIntersection,TypeGuardTupleUnwrap.Note: The V3 concrete struct types (
V3.StringStruct,V3.NumberStruct, etc.) were never available as bare flat imports — they were always inside the V3 namespace on the originaldeveloperbranch. This PR does not change that.Key change: Rules barrel wildcard → explicit allowlist
Similarly,
src/validators/rules/index.tspreviously usedexport * from ./types/index.ts, which re-exportedCUSTOM_RULE_BRAND(a runtimeunique symbolused internally for type branding) andRuleStruct<Rule>(an internal dispatch type). These are now excluded from the public API by replacing the wildcard with an explicit type allowlist. Internal consumers still import these directly from./types/index.ts.Key change: GetSchema edge cases
GetSchema<any>: Previously mis-mapped toFluentSchema<string, StringSchemaRules>becauseanydistributes through conditionals. Now uses the0 extends (1 & T)guard pattern to detectanyearly, correctly resolving toFluentSchema<any>.GetSchema<unknown>: Previously returnedneverbecauseunknownfails all conditional branches. Now has an explicit branch mapping toFluentSchema<any>.GetSchema<void>: Added explicit branch mapping toFluentSchema<any>. Previously fell through tonever.GetSchema<never>: Explicitly returnsnever— intentional, sinceneverinputs should produceneveroutputs.GetSchema<Record<K, V>>: Previously usedPropertyKey extends keyof Twhich never matched any Record type becausesymboldoesn't extendstringornumber. All Records silently fell through to the "specific object" branch, losingRecordSchemaRules(including.nonEmpty()). Now uses per-key-type checks:string extends keyof T,number extends keyof T,symbol extends keyof T— correctly detecting Records with any broad key type.neverfallbacks: The broadstring/numberdetection branches ([string] extends [T],[number] extends [T]) have documentedneverfallbacks for cases where[K] extends [T]is true butT extends Kis false. These are unreachable because the only such types areanyandunknown, both caught earlier, but the fallbacks are safety nets documented for future maintainers.Test Plan
yarn tsc -p tsconfig.json --noEmit— all type assertions passyarn tsc -p tsconfig.esm.json --noEmit— ESM typecheck passesyarn tsc -p tsconfig.cjs.json --noEmit— CJS typecheck passesyarn test— 382 passed, 1 skippedyarn build— ESM + CJS outputs generatedyarn check:fix— lint + format cleanyarn circular-dependencies— 0 circular deps@srhenry/type-utilsentryGetSchematype-level assertions compile correctly (all cases includingany,unknown,void,never,Record<string,V>,Record<number,V>,Record<symbol,V>, function, Date)RecordSchemaRulesis present (not{}), ensuring.nonEmpty()method is availableCUSTOM_RULE_BRANDandRuleStructno longer in public API