@@ -522,4 +522,310 @@ describe('schema', () => {
522522 } > ( value [ 1 ] ) ;
523523 expectType < ObjectId > ( value [ 0 ] ?. _id ) ;
524524 } ) ;
525+
526+ test ( 'explicit optional - simple' , ( ) => {
527+ const value = schema ( {
528+ bar : types . number ( { required : true } ) ,
529+ foo : types . boolean ( { required : false } ) ,
530+ } ) ;
531+
532+ expect ( value ) . toEqual ( {
533+ $validationAction : 'error' ,
534+ $validationLevel : 'strict' ,
535+ additionalProperties : false ,
536+ properties : {
537+ __v : {
538+ type : 'number' ,
539+ } ,
540+ _id : {
541+ bsonType : 'objectId' ,
542+ } ,
543+ bar : {
544+ type : 'number' ,
545+ } ,
546+ foo : {
547+ type : 'boolean' ,
548+ } ,
549+ } ,
550+ required : [ '_id' , 'bar' ] ,
551+ type : 'object' ,
552+ } ) ;
553+
554+ expectType <
555+ [
556+ {
557+ _id : ObjectId ;
558+ foo ?: boolean ;
559+ bar : number ;
560+ } ,
561+ { }
562+ ]
563+ > ( value ) ;
564+ expectType < ObjectId > ( value [ 0 ] ?. _id ) ;
565+ expectType < boolean | undefined > ( value [ 0 ] ?. foo ) ;
566+ expectType < typeof value [ 0 ] > ( {
567+ _id : new ObjectId ( ) ,
568+ bar : 123 ,
569+ foo : true ,
570+ } ) ;
571+ expectType < typeof value [ 0 ] > ( {
572+ _id : new ObjectId ( ) ,
573+ bar : 123 ,
574+ } ) ;
575+ } ) ;
576+
577+ test ( 'explicit optional - full' , ( ) => {
578+ const value = schema (
579+ {
580+ anyOptional : types . any ( { required : false } ) ,
581+ anyRequired : types . any ( { required : true } ) ,
582+ arrayOfObjects : types . array (
583+ types . object (
584+ {
585+ foo : types . number ( ) ,
586+ } ,
587+ { required : true }
588+ )
589+ ) ,
590+ arrayOptional : types . array ( types . number ( { required : false } ) ) ,
591+ arrayRequired : types . array ( types . number ( ) , { required : true } ) ,
592+ binaryOptional : types . binary ( { required : false } ) ,
593+ binaryRequired : types . binary ( { required : true } ) ,
594+ booleanOptional : types . boolean ( { required : false } ) ,
595+ booleanRequired : types . boolean ( { required : true } ) ,
596+ dateOptional : types . date ( { required : false } ) ,
597+ dateRequired : types . date ( { required : true } ) ,
598+ enumOptional : types . enum ( [ ...Object . values ( TEST_ENUM ) , null ] ) ,
599+ enumRequired : types . enum ( Object . values ( TEST_ENUM ) , { required : true } ) ,
600+ numberOptional : types . number ( { required : false } ) ,
601+ numberRequired : types . number ( { required : true } ) ,
602+ objectGenericOptional : types . objectGeneric ( types . number ( { required : false } ) ) ,
603+ objectGenericRequired : types . objectGeneric ( types . number ( ) , 'abc.+' , { required : true } ) ,
604+ objectIdOptional : types . objectId ( { required : false } ) ,
605+ objectIdRequired : types . objectId ( { required : true } ) ,
606+ objectOptional : types . object ( {
607+ foo : types . number ( { required : false } ) ,
608+ } ) ,
609+ objectRequired : types . object (
610+ {
611+ foo : types . number ( { required : false } ) ,
612+ } ,
613+ { required : true }
614+ ) ,
615+ stringOptional : types . string ( { required : false } ) ,
616+ stringRequired : types . string ( { required : true } ) ,
617+ } ,
618+ {
619+ defaults : { stringOptional : 'foo' } ,
620+ timestamps : true ,
621+ validationAction : VALIDATION_ACTIONS . WARN ,
622+ validationLevel : VALIDATION_LEVEL . MODERATE ,
623+ }
624+ ) ;
625+
626+ expect ( value ) . toEqual ( {
627+ $defaults : { stringOptional : 'foo' } ,
628+ $validationAction : 'warn' ,
629+ $validationLevel : 'moderate' ,
630+ additionalProperties : false ,
631+ properties : {
632+ __v : {
633+ type : 'number' ,
634+ } ,
635+ _id : {
636+ bsonType : 'objectId' ,
637+ } ,
638+ anyOptional : {
639+ bsonType : [
640+ 'array' ,
641+ 'binData' ,
642+ 'bool' ,
643+ 'date' ,
644+ 'null' ,
645+ 'number' ,
646+ 'object' ,
647+ 'objectId' ,
648+ 'string' ,
649+ ] ,
650+ } ,
651+ anyRequired : {
652+ bsonType : [
653+ 'array' ,
654+ 'binData' ,
655+ 'bool' ,
656+ 'date' ,
657+ 'null' ,
658+ 'number' ,
659+ 'object' ,
660+ 'objectId' ,
661+ 'string' ,
662+ ] ,
663+ } ,
664+ arrayOfObjects : {
665+ items : {
666+ additionalProperties : false ,
667+ properties : {
668+ foo : {
669+ type : 'number' ,
670+ } ,
671+ } ,
672+ type : 'object' ,
673+ } ,
674+ type : 'array' ,
675+ } ,
676+ arrayOptional : {
677+ items : {
678+ type : 'number' ,
679+ } ,
680+ type : 'array' ,
681+ } ,
682+ arrayRequired : {
683+ items : {
684+ type : 'number' ,
685+ } ,
686+ type : 'array' ,
687+ } ,
688+ binaryOptional : {
689+ bsonType : 'binData' ,
690+ } ,
691+ binaryRequired : {
692+ bsonType : 'binData' ,
693+ } ,
694+ booleanOptional : {
695+ type : 'boolean' ,
696+ } ,
697+ booleanRequired : {
698+ type : 'boolean' ,
699+ } ,
700+ createdAt : {
701+ bsonType : 'date' ,
702+ } ,
703+ dateOptional : {
704+ bsonType : 'date' ,
705+ } ,
706+ dateRequired : {
707+ bsonType : 'date' ,
708+ } ,
709+ enumOptional : {
710+ enum : [ 'foo' , 'bar' , null ] ,
711+ } ,
712+ enumRequired : {
713+ enum : [ 'foo' , 'bar' ] ,
714+ } ,
715+ numberOptional : {
716+ type : 'number' ,
717+ } ,
718+ numberRequired : {
719+ type : 'number' ,
720+ } ,
721+ objectGenericOptional : {
722+ additionalProperties : false ,
723+ patternProperties : {
724+ '.+' : {
725+ type : 'number' ,
726+ } ,
727+ } ,
728+ type : 'object' ,
729+ } ,
730+ objectGenericRequired : {
731+ additionalProperties : false ,
732+ patternProperties : {
733+ 'abc.+' : {
734+ type : 'number' ,
735+ } ,
736+ } ,
737+ type : 'object' ,
738+ } ,
739+
740+ objectIdOptional : {
741+ bsonType : 'objectId' ,
742+ } ,
743+ objectIdRequired : {
744+ bsonType : 'objectId' ,
745+ } ,
746+ objectOptional : {
747+ additionalProperties : false ,
748+ properties : {
749+ foo : {
750+ type : 'number' ,
751+ } ,
752+ } ,
753+ type : 'object' ,
754+ } ,
755+ objectRequired : {
756+ additionalProperties : false ,
757+ properties : {
758+ foo : {
759+ type : 'number' ,
760+ } ,
761+ } ,
762+ type : 'object' ,
763+ } ,
764+ stringOptional : {
765+ type : 'string' ,
766+ } ,
767+ stringRequired : {
768+ type : 'string' ,
769+ } ,
770+ updatedAt : {
771+ bsonType : 'date' ,
772+ } ,
773+ } ,
774+ required : [
775+ '_id' ,
776+ 'anyRequired' ,
777+ 'arrayRequired' ,
778+ 'binaryRequired' ,
779+ 'booleanRequired' ,
780+ 'dateRequired' ,
781+ 'enumRequired' ,
782+ 'numberRequired' ,
783+ 'objectGenericRequired' ,
784+ 'objectIdRequired' ,
785+ 'objectRequired' ,
786+ 'stringRequired' ,
787+ 'createdAt' ,
788+ 'updatedAt' ,
789+ ] ,
790+ type : 'object' ,
791+ } ) ;
792+
793+ /* eslint-disable */
794+ expectType < {
795+ _id : ObjectId ;
796+ anyOptional ?: any ;
797+ // This `any` can not be required in TS
798+ anyRequired ?: any ;
799+ arrayOptional ?: ( number | undefined ) [ ] ;
800+ arrayRequired : ( number | undefined ) [ ] ;
801+ arrayOfObjects ?: {
802+ foo ?: number ;
803+ } [ ] ;
804+ binaryOptional ?: Binary ;
805+ binaryRequired : Binary ;
806+ booleanOptional ?: boolean ;
807+ booleanRequired : boolean ;
808+ dateOptional ?: Date ;
809+ dateRequired : Date ;
810+ enumOptional ?: TEST_ENUM | null ;
811+ enumRequired : TEST_ENUM ;
812+ numberOptional ?: number ;
813+ numberRequired : number ;
814+ objectGenericOptional ?: { [ key : string ] : number | undefined } ;
815+ objectGenericRequired : { [ key : string ] : number | undefined } ;
816+ objectIdOptional ?: ObjectId ;
817+ objectIdRequired : ObjectId ;
818+ objectOptional ?: { foo ?: number } ;
819+ objectRequired : { foo ?: number } ;
820+ stringOptional ?: string ;
821+ stringRequired : string ;
822+ createdAt : Date ;
823+ updatedAt : Date ;
824+ } > ( value [ 0 ] ) ;
825+ /* eslint-enable */
826+ expectType < {
827+ stringOptional : string ;
828+ } > ( value [ 1 ] ) ;
829+ expectType < ObjectId > ( value [ 0 ] ?. _id ) ;
830+ } ) ;
525831} ) ;
0 commit comments