Skip to content

Commit

Permalink
feat: only resolve "strip()" for schema when used as an object field (#…
Browse files Browse the repository at this point in the history
…1977)

```
string().strip().cast() // string | undefined

object({
   unused: string().strip()
}).cast()  // {}
```

Co-authored-by: jquense <[email protected]>
  • Loading branch information
jquense and jquense authored Apr 12, 2023
1 parent edfe6ac commit 2ba1104
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 22 deletions.
14 changes: 12 additions & 2 deletions src/util/objectTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,19 @@ export type ObjectShape = { [k: string]: ISchema<any> | Reference };

export type AnyObject = { [k: string]: any };

export type ResolveStrip<T extends ISchema<any>> = T extends ISchema<
any,
any,
infer F
>
? Extract<F, 's'> extends never
? T['__outputType']
: never
: T['__outputType'];

export type TypeFromShape<S extends ObjectShape, _C> = {
[K in keyof S]: S[K] extends ISchema<any, any>
? S[K]['__outputType']
[K in keyof S]: S[K] extends ISchema<any>
? ResolveStrip<S[K]>
: S[K] extends Reference<infer T>
? T
: unknown;
Expand Down
14 changes: 6 additions & 8 deletions src/util/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,14 @@ export type ToggleDefault<F extends Flags, D> = Preserve<
? SetFlag<F, 'd'>
: UnsetFlag<F, 'd'>;

export type ResolveFlags<T, F extends Flags, D = T> = Preserve<
export type ResolveFlags<T, F extends Flags, D = T> = Extract<
F,
's'
'd'
> extends never
? Extract<F, 'd'> extends never
? T
: D extends undefined
? T
: Defined<T>
: never;
? T
: D extends undefined
? T
: Defined<T>;

export type Concat<T, U> = NonNullable<T> & NonNullable<U> extends never
? never
Expand Down
62 changes: 50 additions & 12 deletions test/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,36 @@ import { create as tuple } from '../../src/tuple';
import { create as lazy } from '../../src/Lazy';
import ObjectSchema, { create as object } from '../../src/object';

import { _ } from '../../src/util/types';
import { ResolveFlags, SetFlag, UnsetFlag, _ } from '../../src/util/types';

ResolveFlags: {
// $ExpectType string | undefined
type _a = ResolveFlags<string | undefined, 'd'>;

// $ExpectType string | undefined
type _b = ResolveFlags<string | undefined, 's'>;

// $ExpectType string
type _c = ResolveFlags<string | undefined, 's' | 'd', string>;

// $ExpectType string | undefined
type _d = ResolveFlags<string | undefined, 's' | '', string>;

// $ExpectType string
type _e = ResolveFlags<string | undefined, SetFlag<'s', 'd'>, string>;

// $ExpectType ""
type _f = UnsetFlag<'d', 'd'>;

// $ExpectType "s"
type _f2 = UnsetFlag<'d' | 's', 'd'>;

// $ExpectType ""
type _f3 = UnsetFlag<'', 'd'>;

// $ExpectType "d"
type _f4 = SetFlag<'', 'd'>;
}

Base_methods: {
// $ExpectType boolean | undefined
Expand All @@ -29,6 +58,10 @@ Base_methods: {

// $ExpectType number | undefined
number().oneOf([1, ref('$foo')]).__outputType;

// type s = StringSchema<string | undefined, any, '', 's' | 'd'>;

// type ss = s['__outputType'];
}

Mixed: {
Expand Down Expand Up @@ -92,7 +125,7 @@ Mixed: {
// $ExpectType "foo" | "bar"
string<'foo' | 'bar'>().defined().validateSync('foo');

// $ExpectType never
// $ExpectType string | undefined
mixed<string>().strip().cast(undefined);

// $ExpectType string | undefined
Expand Down Expand Up @@ -196,7 +229,7 @@ Strings: {
// $ExpectType "foo" | "bar"
string<'foo' | 'bar'>().defined().validateSync('foo');

// $ExpectType never
// $ExpectType string | undefined
string().strip().cast(undefined);

// $ExpectType string | undefined
Expand Down Expand Up @@ -295,7 +328,7 @@ Numbers: {
// $ExpectType number
numDefaultRequired.validateSync(null);

// $ExpectType never
// $ExpectType number | undefined
number().strip().cast(undefined);

// $ExpectType number | undefined
Expand Down Expand Up @@ -380,7 +413,7 @@ date: {
// $ExpectType Date
dtDefaultRequired.validateSync(null);

// $ExpectType never
// $ExpectType Date | undefined
date().strip().cast(undefined);

// $ExpectType Date | undefined
Expand Down Expand Up @@ -452,7 +485,7 @@ bool: {
// $ExpectType NonNullable<boolean | null | undefined>
blDefaultRequired.validateSync(null);

// $ExpectType never
// $ExpectType boolean | undefined
bool().strip().cast(undefined);

// $ExpectType boolean | undefined
Expand Down Expand Up @@ -584,7 +617,7 @@ Array: {
// $ExpectType (number | undefined)[]
array(number()).concat(array(number()).required()).validateSync([]);

// $ExpectType never
// $ExpectType any[] | undefined
array().strip().cast(undefined);

// $ExpectType any[] | undefined
Expand Down Expand Up @@ -759,7 +792,7 @@ Object: {
const obj = object({
string: string<'foo'>().defined(),
number: number().default(1),
removed: number().strip(),
removed: number().strip().default(0),
ref: ref('string'),
nest: object({
other: string(),
Expand All @@ -780,14 +813,19 @@ Object: {
// $ExpectType "foo"
cast1!.string;

// @ts-expect-error Removed doesn't exist
cast1!.removed;

// $ExpectType number
cast1!.number;

// $ExpectType never
object().strip().cast(undefined);
// $ExpectType string
string().strip().default('').cast('');

// $ExpectType {}
object().strip().strip(false).cast(undefined);
// $ExpectType { string?: string | undefined; }
const _cast2 = object({
string: string().strip().strip(false),
}).cast(undefined);

//
// Object Defaults
Expand Down

0 comments on commit 2ba1104

Please sign in to comment.