@@ -389,12 +389,12 @@ describe('dict', () => {
389389} ) ;
390390
391391describe ( 'optional' , ( ) => {
392- describe ( 'decoding an interface with optional fields' , ( ) => {
393- interface User {
394- id : number ;
395- isDog ?: boolean ;
396- }
392+ interface User {
393+ id : number ;
394+ isDog ?: boolean ;
395+ }
397396
397+ describe ( 'decoding an interface with optional fields' , ( ) => {
398398 const decoder = object < User > ( {
399399 id : number ( ) ,
400400 isDog : optional ( boolean ( ) )
@@ -416,6 +416,36 @@ describe('optional', () => {
416416 } ) ;
417417 } ) ;
418418 } ) ;
419+
420+ it ( 'supports map' , ( ) => {
421+ const decoder = object < User > ( {
422+ id : number ( ) ,
423+ isDog : optional ( number ( ) ) . map ( num => num !== 0 )
424+ } ) ;
425+
426+ expect ( decoder . run ( { id : 1 , isDog : 0 } ) ) . toEqual ( { ok : true , result : { id : 1 , isDog : false } } ) ;
427+ expect ( decoder . run ( { id : 1 , isDog : 77 } ) ) . toEqual ( { ok : true , result : { id : 1 , isDog : true } } ) ;
428+ expect ( decoder . run ( { id : 1 } ) ) . toEqual ( { ok : true , result : { id : 1 } } ) ;
429+ } ) ;
430+
431+ it ( 'supports andThen' , ( ) => {
432+ const decoder = object < User > ( {
433+ id : number ( ) ,
434+ isDog : optional ( string ( ) ) . andThen (
435+ dogName =>
436+ dogName . toLowerCase ( ) [ 0 ] === 'd'
437+ ? succeed ( true )
438+ : fail ( `${ dogName } is not a dog, all dog names start with 'D'` )
439+ )
440+ } ) ;
441+
442+ expect ( decoder . run ( { id : 1 , isDog : 'Doug' } ) ) . toEqual ( { ok : true , result : { id : 1 , isDog : true } } ) ;
443+ expect ( decoder . run ( { id : 1 , isDog : 'Wanda' } ) ) . toMatchObject ( {
444+ ok : false ,
445+ error : { message : "Wanda is not a dog, all dog names start with 'D'" }
446+ } ) ;
447+ expect ( decoder . run ( { id : 1 } ) ) . toEqual ( { ok : true , result : { id : 1 } } ) ;
448+ } ) ;
419449} ) ;
420450
421451describe ( 'oneOf' , ( ) => {
@@ -521,7 +551,7 @@ describe('withDefault', () => {
521551} ) ;
522552
523553describe ( 'valueAt' , ( ) => {
524- describe ( 'decode an value' , ( ) => {
554+ describe ( 'decode a value accessed from a path ' , ( ) => {
525555 it ( 'can decode a single object field' , ( ) => {
526556 const decoder = valueAt ( [ 'a' ] , string ( ) ) ;
527557 expect ( decoder . run ( { a : 'boots' , b : 'cats' } ) ) . toEqual ( { ok : true , result : 'boots' } ) ;
@@ -563,7 +593,10 @@ describe('valueAt', () => {
563593 } ) ;
564594
565595 describe ( 'decode an optional field' , ( ) => {
566- const decoder = valueAt ( [ 'a' , 'b' , 'c' ] , oneOf ( string ( ) , constant ( undefined ) ) ) ;
596+ const decoder : Decoder < string | undefined > = valueAt (
597+ [ 'a' , 'b' , 'c' ] ,
598+ union ( string ( ) , constant ( undefined ) )
599+ ) ;
567600
568601 it ( 'fails when the path does not exist' , ( ) => {
569602 const error = decoder . run ( { a : { x : 'cats' } } ) ;
0 commit comments