Skip to content

Commit

Permalink
fix: mixed() is the the base class
Browse files Browse the repository at this point in the history
fixes #1156
  • Loading branch information
jquense committed Dec 8, 2020
1 parent 67de534 commit 7f8591d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 16 deletions.
4 changes: 2 additions & 2 deletions docs/extending.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function parseDateFromFormats(formats, parseStrict) {
yup.addMethod(yup.date, 'format', parseDateFromFormats);
```

Note that `addMethod` isn't really magic, it mutates the prototype of the passed in schema.
Note that `addMethod` isn't magic, it mutates the prototype of the passed in schema.

> Note: if you are using TypeScript you also need to adjust the class or interface
> see the [typescript](./typescript) docs for details.
Expand All @@ -49,7 +49,7 @@ Note that `addMethod` isn't really magic, it mutates the prototype of the passed

If you're use case calls for creating an entirely new type. inheriting from
and existing schema class may be best: Generally you should not inheriting from
the abstract `Schema` unless you know what you are doing. The other types are fair game though.
the abstract `BaseSchema` unless you know what you are doing. The other types are fair game though.

You should keep in mind some basic guidelines when extending schemas:

Expand Down
10 changes: 10 additions & 0 deletions docs/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,13 @@ declare module 'yup' {
> Watch out!: If your method needs to adjust schema generics, you likely
> need to also extend the Required*, and Defined* interfaces associated with
> each basic type. Consult the core types for examples on how to do this
Be careful of the yup type hierarchy as it's a bit tricky. All schema (including `mixed`)
extend the abstract `BaseSchema` class.

### Special note about MixedSchema and BaseSchema

As far as typescript is concerned, `mixed` schema inherit from `BaseSchema` like other schema; all other schema do **not** extend `MixedSchema`. **In actuality** Mixed is an alias for BaseSchema, meaning `addMethod(mixed)` will add a new method to all schema.

This means that type extensions to `mixed` should generally be put on `BaseSchema` if
you want the method to be available to all sub classes.
26 changes: 12 additions & 14 deletions src/mixed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,11 @@ import { AnyObject, Maybe, Optionals } from './types';
import type { Defined } from './util/types';
import BaseSchema from './schema';

export function create<TType = any>() {
return new MixedSchema<TType | undefined>();
}

export default class MixedSchema<
declare class MixedSchema<
TType = any,
TContext = AnyObject,
TOut = TType
> extends BaseSchema<TType, TContext, TOut> {}

create.prototype = MixedSchema.prototype;

export default interface MixedSchema<
TType = any,
TContext = AnyObject,
TOut = TType
> {
> extends BaseSchema<TType, TContext, TOut> {
default<TNextDefault extends Maybe<TType>>(
def: TNextDefault | (() => TNextDefault),
): TNextDefault extends undefined
Expand All @@ -46,3 +34,13 @@ export default interface MixedSchema<
nullable(isNullable?: true): MixedSchema<TType | null, TContext>;
nullable(isNullable: false): MixedSchema<Exclude<TType, null>, TContext>;
}

const Mixed: typeof MixedSchema = BaseSchema as any;

export default Mixed;

export function create<TType = any>() {
return new Mixed<TType | undefined>();
}
// XXX: this is using the Base schema so that `addMethod(mixed)` works as a base class
create.prototype = Mixed.prototype;
14 changes: 14 additions & 0 deletions test/yup.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
NumberSchema,
BooleanSchema,
DateSchema,
mixed,
MixedSchema,
} from '../src';

describe('Yup', function () {
Expand Down Expand Up @@ -191,6 +193,18 @@ describe('Yup', function () {
});

describe('addMethod', () => {
it('extending mixed should make method accessible everywhere', () => {
addMethod(mixed, 'foo', () => 'here');

expect(string().foo()).to.equal('here');
});

it('extending Mixed should make method accessible everywhere', () => {
addMethod(MixedSchema, 'foo', () => 'here');

expect(string().foo()).to.equal('here');
});

test.each([
['object', object],
['array', array],
Expand Down

0 comments on commit 7f8591d

Please sign in to comment.